C# 反射 特性 序列化 动态编程

  • 时间:
  • 浏览:
  • 来源:互联网

反射

运行时
操作某个类型的元数据

两种方法:
1.实例.getType()
2.typeof(类型)
3.注: 一个类型只有一个type

            var a = new A();
            var type1 = typeof(A);  // typeof(类型)
            var type2 = a.GetType(); // 实例.getType()
            Console.WriteLine("他们的类型是一样的"+type1.Equals(type2));

在这里插入图片描述
我们看看Type里面有什么东西

Type.name
我们现在开始使用吧!
在这里插入图片描述

  class Program
    {
        class A { //通过反射调用方法
         public string MyProperty { get; set; }
         public void Func(int a) { Console.WriteLine(a); }
        
        }  //一个类型
        static void Main(string[] args)
        {
            //反射 运行时操作某个类型的元数据
            //两种实例方法 
            //注意: 一个类型只有一个type
            //var type2 = a.GetType(); // 实例.getType()
            //Console.WriteLine("他们的类型是一样的"+type1.Equals(type2));
            var type = typeof(A);  // typeof(类型)
            var a = new A();
            //GetProperty SetValue 使用方法
            var property = type.GetProperty("MyProperty"); //我在property上拿到一个MyProperty属性,并且给他赋值aaa
            property.SetValue(a,"aaa",null); //第一个 obj value index
            //GetMethod  Invoke 使用方法
            var funcion = type.GetMethod("Func");
            funcion.Invoke(a, new object[] { 1 });

            Console.WriteLine(a.MyProperty);
            
        }

在这里插入图片描述
用反射实现 用户输入A,则执行A,用户输入B,则执行B

        class A { //通过反射调用方法
         public string MyProperty { get; set; }
         public void Func(int a) { Console.WriteLine(a); }

         public void A1() { Console.WriteLine("in function A1"); }
         public void B1() { Console.WriteLine("in function B1"); }

            //用反射实现
            //用户输入A,则执行A
            //用户输入B,则执行B
           string input= Console.ReadLine(); 
           var funcion = type.GetMethod(input);
           funcion.Invoke(a, null);
            //switch (input) //旧方法
            //{
            //    case "a":
            //        break;
            //    case "b":
            //        break;
            //}

            Console.WriteLine(a.MyProperty);
            
        }  //一个类型

在这里插入图片描述

在这里插入图片描述
根据字符串 创建类


            Assembly
            .Load("程序集名称")
            .CreateInstance("命名空间.类名");

在这里插入图片描述

特性

展示一下程序集文件中的特性

用途

体用一个额外元数据

例子:比如设定属性为必填项

旧方法虽然可以放到很多类中检测,但是如果有很多类呢?很麻烦,这个方法已经一劳永逸了。
在这里插入图片描述

       public  class A
        { //通过反射调用方法
         [Required]
         public string MyProperty { get; set; }
         public void Func(int a) { Console.WriteLine(a); }

         //public bool Check() {  //旧方法
         //  if (MyProperty == null) return false;return true;
         //}

         //public void A1() { Console.WriteLine("in function a.A1"); } //都有相同的方法
         //public void B1() { Console.WriteLine("in function a.B1"); }

        }
        public class RequiredAttribute : System.Attribute {
            public static bool IsPropertyRequired(object obj) {
                var type = obj.GetType();
                var properties = type.GetProperties();
                foreach (var propetry in properties)
                {
                    var attributes = propetry.GetCustomAttributes(typeof(RequiredAttribute),false);
                    if (attributes.Length>0)
                    {
                        if (propetry.GetValue(obj,null)==null)
                      
                            return false;

                    }
                    
                }
                return true;
            }
        }

        var a = new A() {  }; //MyProperty="123"未赋值 
            if (RequiredAttribute.IsPropertyRequired(a))
            {
                Console.WriteLine("已经赋值");
            }
            else
            {
                Console.WriteLine("未赋值");
            }

序列化 反序列化

如何将一个实例 序列化为文件 然后反序列化
在这里插入图片描述

 [Serializable] //可序列化
        public class A
        {
            public string Test = "123";
        }
  //序列化
                var a = new A();
                using (var steam = File.Open(typeof(A).Name + "bin", FileMode.Create))
                {
                    var bf = new BinaryFormatter();
                    bf.Serialize(steam, a);
                }
                //反序列化
                A after = null;
                using (var steam = File.Open(typeof(A).Name + "bin",        FileMode.Open))
                {
                    var bf = new BinaryFormatter();
                    after = (A)bf.Deserialize(steam);
                }
                Console.WriteLine(after.Test);

MSDN:stream是所有流的抽象基类,流是字节序列的抽象概念。例如文件,输入/输出设备 ,内部进程通信管道或者TCP/IP套接字。

我的理解:流是数据交换和传输的方式,方式上:文件流 网络流 内侧流,方向上 输入流 输出流。

流的继承体系

##

动态编程

仅介绍一个应用场景
解析XML文件
链接: 引用大佬的博客.

            string xml = @"
                <books>
                <book></book>
                <book><title>余华文城</title></book>
                </books>
                 ";
                dynamic dyname = new DynamicXml(xml);
                Console.WriteLine(dyname.book[1].title.Value);

引入一个类

using System;
using System.Collections;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace SerializeDemo
{
    public class DynamicXml : DynamicObject, IEnumerable
    {
        private readonly List<XElement> _elements;

        public DynamicXml(string text)
        {
            var doc = XDocument.Parse(text);
            _elements = new List<XElement> { doc.Root };
        }

        protected DynamicXml(XElement element)
        {
            _elements = new List<XElement> { element };
        }

        protected DynamicXml(IEnumerable<XElement> elements)
        {
            _elements = new List<XElement>(elements);
        }

        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            result = null;
            if (binder.Name == "Value")
                result = _elements[0].Value;
            else if (binder.Name == "Count")
                result = _elements.Count;
            else
            {
                var attr = _elements[0].Attribute(
                    XName.Get(binder.Name));
                if (attr != null)
                    result = attr;
                else
                {
                    var items = _elements.Descendants(
                        XName.Get(binder.Name));
                    if (items == null || items.Count() == 0)
                        return false;
                    result = new DynamicXml(items);
                }
            }
            return true;
        }

        public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
        {
            int ndx = (int)indexes[0];
            result = new DynamicXml(_elements[ndx]);
            return true;
        }

        public IEnumerator GetEnumerator()
        {
            foreach (var element in _elements)
                yield return new DynamicXml(element);
        }
}
}

总结:反射很重要,动态加载类,特性的各种东西。

本文链接http://www.dzjqx.cn/news/show-617481.html