C#之反射

2021-06-20 10:04

阅读:600

标签:const   除了   很多   实例化   for   函数名   重要   each   string   

反射是给你一个程序集dll,可以反射出其中的所有元数据metadata,包括字段、属性、方法等,反射最重要的重要就是利用反射创建对象,从而达到层与层之间的低耦合效果。IOC依赖注入容器就是反射典型的应用场景,包过MVC、ORM都用到了反射。反射在我们程序设计中是无处不在的,只不过现在有很多第三方的框架、组件帮我们封装好了,有时候感觉不到反射的应用,下面我们就深入了解一下反射。

1.反射创建对象

1//常规创建对象的方法 
IDBHelper iDBHelper = new MySqlHelper(); 2 iDBHelper.Query(); 3 //这种代码我们应该经常写 使用接口仍然避免不了对MySqlHelper所在类的dll的依赖
Assembly assembly = Assembly.Load("MySql");//1.加载程序集  注意:一定要在主项目中添加该类库的引用 该dll要和exe文件在同一个文件夹中
                    Type type = assembly.GetType("MySql.MySqlHelper");//2.获取程序集中指定的对象类型
                    IDBHelper iDBHelper = (IDBHelper)Activator.CreateInstance(type);//3.创建对象
                    iDBHelper.Query();

                    //反射获取该类型中的所有公共方法
                    foreach (var t in type.GetMethods())
                    {
                        Console.WriteLine(t.Name);
                    }
                    //反射获取该类型中的所有公共属性
                    foreach (var t in type.GetProperties())
                    {
                        Console.WriteLine(t.Name);
                    }

2.上面只是说明了反射可以创建无参构造函数,反射还可以创建带参数的构造函数。

 public class MySqlHelper : IDBHelper
    {
       
        public string Name { get; set; }
        protected int Age { get; set; }
        
        public  MySqlHelper()
        {
            Console.WriteLine("{0}被构造-无参",this.GetType().Name);
        }
        public MySqlHelper(string Name)
        {
            this.Name = Name;
            Console.WriteLine("带有一个参数构造被构建");
        }
        public MySqlHelper(string Name, int Age)
        {
            this.Name = Name;
            this.Age = Age;
            Console.WriteLine("带有两个参数构造函数别构建");
        }
        public void Query()
        {
            Console.WriteLine("{0}.Query",this.GetType().Name);
        }
        protected void Fun()
        {
        }
    }

#region 反射创建对象-有参构造函数
{
Assembly assembly = Assembly.Load("MySql");
Type type = assembly.GetType("MySql.MySqlHelper");
//遍历所有公共构造函数
foreach (var t in type.GetConstructors())
{
Console.WriteLine("构造函数名:"+t.Name);
foreach (var p in t.GetParameters())
{
Console.WriteLine(p.ParameterType);
}
}
IDBHelper dBHelper = (IDBHelper)Activator.CreateInstance(type);
IDBHelper dBHelper2 = (IDBHelper)Activator.CreateInstance(type,new object[] { "张三"});
IDBHelper dBHelper3 = (IDBHelper)Activator.CreateInstance(type,new object[] { "李四",18});
}
#endregion

 

运行结果:

技术分享图片

4.我们都知道当我们在程序设计的时候运用到了单例模式,该对象只可能被实例化一次。。但是。。。运用反射可以 破坏单例模式 。  即反射可以调用私有构造函数从而创建对象。

 public class SqlServerHelper:IDBHelper
    {
        //public SqlServerHelper()
        //{
        //  Console.WriteLine("{0}被构造",this.GetType().Name);
        // }
        private SqlServerHelper()
        {
            Console.WriteLine("无参构造函数被创建");
        }
        public void Query()
        {
            Console.WriteLine("{0}被构造",this.GetType().Name);
        }
    }
 public class SqlServerHelper:IDBHelper
    {
        //public SqlServerHelper()
        //{
        //  Console.WriteLine("{0}被构造",this.GetType().Name);
        // }
        private SqlServerHelper()
        {
            Console.WriteLine("无参构造函数被创建");
        }
        public void Query()
        {
            Console.WriteLine("{0}被构造",this.GetType().Name);
        }
    }


 #region 反射破坏单例  调用私有构造函数创建对象
                {
                    Console.WriteLine("反射调用私有构造函数创建对象");
                    Assembly assembly = Assembly.Load("SqlServer");
                    Type type = assembly.GetType("SqlServer.SqlServerHelper");
                    IDBHelper dBHelper = (IDBHelper)Activator.CreateInstance(type,true);//可以调用私有构造函数
                    dBHelper.Query();
                }
                #endregion

程序结果:

技术分享图片

5.反射创建泛型对象

 public class GenericClass
    {
        public GenericClass()
        {
            Console.WriteLine("泛型对象被创建"+typeof(T)+typeof(S));
        }
       
    }
 #region 反射创建泛型对象
                {
                    Console.WriteLine("反射创建泛型对象");
                    Assembly assembly = Assembly.Load("MySql");
                    //Type type = assembly.GetType("MySql.GenericClass");
                    Type type = assembly.GetType("MySql.GenericClass`2");//泛型类获取对象
                    Type genericType = type.MakeGenericType(new Type[] { typeof(int),typeof(string)});
                    object genericObject = Activator.CreateInstance(genericType);
                   
                }
                #endregion

程序结果:

技术分享图片

反射除了创建创建对象  还可以调用方法,获取字段、属性功能

C#之反射

标签:const   除了   很多   实例化   for   函数名   重要   each   string   

原文地址:https://www.cnblogs.com/hzpblogs/p/10264110.html


评论


亲,登录后才可以留言!