C#中的事件,委托,抽象(密封)类,接口,反射,序列化基础

一.事件

  • 类或对象可以通过事件向其他类或对象通知发生的相关事情。发送(或引发)事件的类称为“发行者”,接收(或处理)事件的类称为“订户”。
  • 事件本质上是一组方法,在某种情况下触发的某种行为,也就是执行某个方法(通过委托实现的,委托才是事件能正常执行的核心内容)(委托是事件能正常执行的保证和核心基础),事件触发后执行哪块代码取决于事件注册在了那个什么方法里(事件实现方法(事件处理程序))。
  //用户自定义登录模块
        //定义验证事件(此事件由用户注册具体实现方法)
        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
发布了21 篇原创文章 · 获赞 3 · 访问量 352

猜你喜欢

转载自blog.csdn.net/MrLsss/article/details/104065767