一.事件
- 类或对象可以通过事件向其他类或对象通知发生的相关事情。发送(或引发)事件的类称为“发行者”,接收(或处理)事件的类称为“订户”。
- 事件本质上是一组方法,在某种情况下触发的某种行为,也就是执行某个方法(通过委托实现的,委托才是事件能正常执行的核心内容)(委托是事件能正常执行的保证和核心基础),事件触发后执行哪块代码取决于事件注册在了那个什么方法里(事件实现方法(事件处理程序))。
//用户自定义登录模块
//定义验证事件(此事件由用户注册具体实现方法)
public event Action<object, MyEventArgs> Moden;
private void btnLogin_Click(object sender, EventArgs e)
{
//点击登录触发验证事件
if (txtusername.Text=="")
{
MessageBox.Show("用户名不能为空!");
}
if (txtuserpassworld.Text=="")
{
MessageBox.Show("密码不能为空!");
}
MyEventArgs Str = new UserCourtro.MyEventArgs();
Str.Name = txtusername.Text.Trim();
Str.PasswWorld = txtuserpassworld.Text;//获取并保存与此事件相关的数据信息
//注册此事件会获得对应两参数据信息和窗体控件(双击事件)一样
Moden(this,Str);//调用验证事件(谁的事件,附加数据)----------执行那个验证动作,如何验证,就看谁注册了这个事件,只提供输入数据
}
}
public class MyEventArgs//保存于此事件相关的数据信息
{
private string name;
private string passwWorld;
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
//---------------------------------具体使用该控件的模块注册事件-----------------
//在加载这个控件的时候注册用户自定义控件的事件
private void userLoginData1_Load(object sender, EventArgs e)
{
//组件加载事件:注册验证事件
//验证方法由用户自己定义
userLoginData1.Moden += UserLoginData1_Moden;
}
private void UserLoginData1_Moden(object arg1, UserCourtro.MyEventArgs arg2)
{
//具体实现方法,arg2里保存了用户控件中获取的用户输入的用户名和密码等帮助数据。
if (arg2.Name == "admin" && arg2.PasswWorld == "123")
{
this.BackColor = Color.Green;
}
else
{
this.BackColor = Color.Red;
}
}
二.密封类
- 关键字hisealed,放在class前,没密封类不能用在基类,密封类主要作用是:防止派生
三.静态类
- 它们只能包含静态成员。
- 它们不能被实例化。
- 它们是密封的
- 它们不能包含实例构造函数。
- 静态类中的构造函数不能有访问修饰符,静态类不能继承其他自定义类也不能别继承,静态方法可以被重载但不能被重写。
四.抽象类
- 关键字:abstract.抽象类不能被实例化,抽象类中的实例化函数不可被调用,只能通过子类来调用,抽象类中不能有抽象构造函数也不能有抽象字段,抽象类的访问修饰符不能为private。
五.接口
- 接口的关键字为:interface,接口中只能有public访问修饰符而且public不能手动再次输入。接口也不能被实例化。
六.委托
- 委托是一种引用方法的类型,一旦委托分配了方法,委托将于该方法具有完全相同的行为。
- 委托是一种数据类型,使用之前需要先定义一个委托类型
- 委托解决的就是把方法当做参数进行传递的问题。
- 委托可以当做参数进行传递,也可以当成返回值,也可以做成数据类型接收对象(方法)。`
public delegate void MyDelegate();//无参无返回值
public delegate int MyDelegate2(int a, int b);//两参一返回值
public delegate T MyDelegate3<T>(T a, T b);//定义泛型委托,T是泛型类型<string>后面参数也会是string
//窗体之间的控制需要关联方法,调用显示直接创建委托对象
//定义无返回值的泛型委托
public delegate void mydelegatevoid<T>(T a, T b);
//声明委托变量,创建委托对象
MyDelegate md1 = () => { MessageBox.Show("我调用的是无参无返回值的委托类型"); };
MyDelegate2 md2 = (x, y) => { return x + y; };//两参一返回值
MyDelegate3<int> md3 = (x, y) => { return x + y; };
//----------------系统委托(泛型)
//定义系统泛型委托
public Action Moden;//非泛型版本 (无参无返回值) Action一定没有返回值
public Action<int, int, int, string> Modens;//泛型版本,有参数无返回值
//有返回值的系统定义的泛型委托
public Func<string> Moden1;//必须有返回值,如果有一个参数,那么就是返回值类型
public Func<string, string, int> Moden2;//泛型版本,前两个参数代表参数类型,最后一个代表返回值类型
委托的特点:
- 委托类似于 C++ 函数指针,但它们是类型安全的。
- 委托允许将方法作为参数进行传递。
- 委托可用于定义回调方法。
- 委托可以链接在一起;例如,可以对一个事件调用多个方法。
- 方法不必与委托签名完全匹配
委托的使用:
- 定义:delegate void moden(int a);
- 定义方法:public void m(int i){Console.WriteLine(“sss”);}
- 关联委托方法:声明委托变量,创建委托对象
MyDelegate2 s = (x, y) => { return x + y; };2.MyDelegate2 mds = new MyDelegate2("MethodName");
委托与事件的区别:
- 委托和事件没有可比性,因为委托是数据类型,事件则是对象(事件也可以说是委托的特殊实例),也可以理解为对委托的封装(编译后生成一个私有委托和两个公共方法ADD和REMOVE)
- 委托一旦被赋值(可以在任何地方去调用),而事件只能在类的内部实现,外部只能+=注册自己,不能主动触发事件,委托就没法进行这种控制,所以有了两种公共方法提供注册和注销不能直接调用触发
- 事件只能+=或者-=来注册或注销事件,而委托可以用=号赋值,因为委托是引用类型,这样会覆盖以前的方法值
七.反射
- 反射:动态加载程序集通过获取其类型,创建对象调用其成员的过程叫做反射(前提有程序集)
//动态加载程序集
Assembly Asm = Assembly.LoadFile(@"C:\Users\俗子。\Desktop\ADO.NET练习\反射01\01Animal\bin\Debug\01Animal.exe");
//获取类型
Type[] type = Asm.GetTypes();//获取所有类型
Asm.GetExportedTypes();//获取程序集内所有公共类型
Type Person = Asm.GetType("_01Animal.person");//获取指定的类型
//获取方法,如果获取重载,则用第二个参数TYPE[]数组表示即可
MethodInfo info = Person.GetMethod("SayHi");//获取指定方法
//创建对象
//object c = Activator.CreateInstance(Person);//无参构造方法创建对象
ConstructorInfo Cons = Person.GetConstructor(new Type[] { typeof(string), typeof(string), typeof(int) });//使用type数组来表示多个参数
object c = Cons.Invoke(new object[] { "张三", "女", 25 });//对象
//执行
object str = info.Invoke(c, null);//执行方法,需要参数(实例对象,方法参数)
MessageBox.Show(str.ToString());//成功!
//获取指定属性
PropertyInfo A = Person.GetProperty("Name");
//MessageBox.Show(A.Name);//获取属性的名称
MessageBox.Show(A.GetValue(c, null).ToString());//获取属性值
PropertyInfo B = Person.GetProperty("Sex");
// MessageBox.Show(B.Name);//获取性别的名称
MessageBox.Show(B.GetValue(c, null).ToString());//获取属性值
PropertyInfo C = Person.GetProperty("Age");
// MessageBox.Show(C.Name.ToString());//获取年龄属性名称
MessageBox.Show(C.GetValue(c, null).ToString());
八.序列化和反序列化
-
[Serializable]//标记为可以被序列化的类
public class Person -
序列化:对象转化为文件的过程(字节流) 反序列化:文件(字节流)转化为对象的过程
-
序列化是通过将对象转换为字节流,从而存储对象或将对象传输到内存,数据库或文件的过程。主要用途是保存对象的状态,包括对象的数据,以便能够在需要是重建对象。反向过程称为 反序列化。
-
**用途:**通过序列化,可以执行如下操作:通过 Web 服务将对象发送到远程应用程序、在域之间传递对象、以 XML 字符串的形式传递对象通过防火墙、跨应用程序维护安全性或用户专属信息。
List<Person> ulist = new List<委托_事件_反射_序列化复习.Person>()
{
new Person() { Name="张三",Sex="男",Age=18},
new Person() { Name="李四",Sex="男",Age=20},
new Person() { Name="王五",Sex="女",Age=22},
new Person() { Name="刘明",Sex="女",Age=25}
};
BinaryFormatter bf = new BinaryFormatter();
using (FileStream fs = new FileStream(@"C:\Users\俗子。\Desktop\序列化.txt", FileMode.Open, FileAccess.ReadWrite))
{
bf.Serialize(fs, ulist);//序列化person对象集合
}
MessageBox.Show("序列化成功!");
//-----------------------------------反序列化-----------------------------------------------
using (FileStream fs = new FileStream(@"C:\Users\俗子。\Desktop\序列化.txt", FileMode.Open, FileAccess.Read))
{
BinaryFormatter cf = new BinaryFormatter();
List<Person> list = cf.Deserialize(fs) as List<Person>;//强转成集合类型,然后遍历输出结果
if (list != null)
{
for (int i = 0; i < list.Count; i++)
{
MessageBox.Show(string.Format("姓名:{0},性别:{1},年龄:{2}", list[i].Name, list[i].Sex, list[i].Age));
}
}
else
{
MessageBox.Show("没有相关数据信息!");
}
}
八.XML序列化和反序列化
#region Xml序列化
//要序列化的数据
List<Person> ulist = new List<Person>()
{
new Person () { Name="小明",Sex="男",Age=20},
new Person () { Name="小红",Sex="女",Age=40},
new Person () { Name="小黑",Sex="男",Age=24},
};
//Xml序列化
XmlSerializer xml = new XmlSerializer(typeof(List<Person>));//需要指明序列化对象类型
//创建文件流
using (FileStream fs = new FileStream("Person.xml", FileMode.Create, FileAccess.Write))
{
xml.Serialize(fs, ulist);
}
MessageBox.Show("Xml序列化成功!");//成功了
#endregion
#region Xml反序列化
//using (FileStream fs = new FileStream("Person.xml", FileMode.Open, FileAccess.Read))
//{
//xml文件序列化需要指定序列化类型
// XmlSerializer xml = new XmlSerializer(typeof(List<Person>));
// List<Person> ulist = xml.Deserialize(fs) as List<Person>;//xml反序列化结果强转list集合
// if (ulist != null)
// {
// for (int i = 0; i < ulist.Count; i++)
// {
// MessageBox.Show(string.Format("姓名:{0},性别:{1},年龄:{2}", ulist[i].Name, ulist[i].Sex, ulist[i].Age));
// //成功
// }
// }
//}
using (FileStream fs = new FileStream("person.xml", FileMode.Open, FileAccess.ReadWrite))
{
//创建xml序列化器
XmlSerializer xml = new XmlSerializer(typeof(List<Person>));
List<Person> ulist = xml.Deserialize(fs) as List<Person>;
this.dataGridView1.DataSource = ulist;
}
#endregion