C#--反射

前言:使用反射也有几年了,但是一直觉得,反这个概念很抽象,今天有时间就来总结下这个知识点。

 

1、为什么需要反射:

  最初使用反射的时候,总是不理解,既然可以通过new 一个对象的方式得到对象,然后通过对象去调用属性和方法,那么为什么还需要反射去调用呢?后来使用多了发现这就是一个先绑定还是后绑定的问题,很多初使用反射的开发人员通常都会有类似这种疑虑:既然在开发时就能够写好代码,干嘛还放到运行期去做,不光繁琐,而且效率也受影响。博主觉得主要是适用性的问题,如果你的系统没有那么高的扩展性和灵活性要求,你大可不必考虑反射。但在架构设计时,很多东西都需要考虑复用性,并且在某些特定的场景下你得不到具体的类时,你就必须用到反射。博主总结了下自己使用过的反射场景:

(1)有时不知道具体的类型,可以通过dll去得到类的对象;

(2)某些特殊方法,传过来的是泛型类,需要通过反射处理某些特殊的业务;

(3)通用方法DataTable和List<T>的相互转化时需要用到反射;

 

2、如何使用反射:

(1)反射dll得到类成员:

在一个未知的dll里面有一个Person类

    public class Person
    {
        private string address;
        private string email;

        public string Name { set; get; }

        public int Age { set; get; }

        public void SayHello()
        {
            Console.WriteLine("你好");
        }

        public static string MystaticPro { set; get; }
        public static void MyStatic()
        {
            Console.WriteLine("我是static方法");
        }
    }

通过反射dll得到Person类

static void Main(string[] args)
        {
            //反射dll
            Type type = typeof(Person);
            //默认得到类下面的所有public成员
            var lstMembers = type.GetMembers();
            foreach (var oMem in lstMembers)
            {
                Console.WriteLine("GetMembers()方法得到的成员名称:" + oMem.Name);
            }
            Console.WriteLine("");

            //默认得到类下面的所有public属性
            var lstProperty = type.GetProperties();
            foreach (var oProp in lstProperty)
            {
                Console.WriteLine("GetProperties()方法得到的成员名称:" + oProp.Name);
            }
            Console.WriteLine("");

            //默认得到类下面的所有public字段
            var lstField = type.GetFields();
            foreach (var oField in lstField)
            {
                Console.WriteLine("GetFields()方法得到的成员名称:" + oField.Name);
            }

            Console.ReadKey();
        }

得到结果

 

(2)反射对象的私有字段:

一般私有属性的用法比较少,我们就以私有字段为例来说明,还是上面的例子:

static void Main(string[] args)
{
    Type type = typeof(Person);
    //默认得到类下面的所有private字段
    var lstField = type.GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
    foreach (var oField in lstField)
    {
        Console.WriteLine("GetFields()方法得到的私有字段名称:" + oField.Name);
    }

    Console.ReadKey();
}

 

(3)反射对象的静态成员:

static void Main(string[] args)
{

    Type type = typeof(Person);
    //默认得到类下面的所有public成员
    var lstMembers = type.GetMembers(BindingFlags.Public | BindingFlags.Static);
    foreach (var oMem in lstMembers)
    {
        Console.WriteLine("GetMembers()方法得到的成员名称:" + oMem.Name);
    }

    Console.ReadKey();
}

还有枚举类型等等就不一一介绍了,基本上都是在BindingFlags这个上面做处理。

 

(4)反射得到对象以及对象的操作:

反射得到对象的方法主要有两种

        public static T GetModel<T>(T oModel)
        {
            var model = default(T) ;
            
            //得到对象的方法一:反射得到泛型类的实体
            model = (T)typeof(T).GetConstructor(new System.Type[] { }).Invoke(new object[] { });

            //得到对象的方法二:
            model = (T)Activator.CreateInstance(typeof(T));

            //逻辑处理......
            
            return model;
        }

对象属性的取值和赋值:

//List集合转换为DataTable
        public static DataTable ListFillTable(object obj)
        {
            if (!(obj is IList))
            {
                return null;
            }
            var objlist = obj as IList;
            if (objlist == null || objlist.Count <= 0)
            {
                return null;
            }
            var tType = objlist[0];
            DataTable dt = new DataTable(tType.GetType().Name);
            DataColumn column;
            DataRow row;
            System.Reflection.PropertyInfo[] myPropertyInfo = tType.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
            foreach (var t in objlist)
            {
                if (t == null)
                {
                    continue;
                }
                row = dt.NewRow();
                for (int i = 0, j = myPropertyInfo.Length; i < j; i++)
                {
                    System.Reflection.PropertyInfo pi = myPropertyInfo[i];
                    string name = pi.Name;
                    if (dt.Columns[name] == null)
                    {
                        var coltype = pi.PropertyType;
                        if (coltype.Name == "Nullable`1")
                        {
                            //coltype = typeof(System.DBNull);
                            column = new DataColumn(name);
                        }
                        else
                        {
                            column = new DataColumn(name, coltype);
                        }
                        dt.Columns.Add(column);
                    }
                    row[name] = pi.GetValue(t, null);
                }
                dt.Rows.Add(row);
            }
            return dt;
        }

 

Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值