zoukankan      html  css  js  c++  java
  • 反射的使用

    反射可以获得Dll里面的类,和对应类的属性,方法,特性,等一系列内容,而不用去添加引用

    获得类中的各个内容

    如何去添加一个Dll,并且获得对应的类,需要用到一个系统类,Assembly,然后使用Assembly.Load(),来导入Dll文件,然后通过Assembly实例的GetType,来获得类库中的具体类,这里面

    的参数需要类的全称,然后根绝methodInfo,Property,field, CustomerAttribute等来获得方法,属性,字段,特性等内容

    添加一个基础类Student

    public class Student
        {
    
            public Student()
            {
                Console.WriteLine("无参构造函数");
            }
    
            public Student(string name, int age)
            {
                Name = name;
                Age = age;
            }
    
    
            public string PetName;
    
            [DisplayName("姓名")]
            public string Name { get; set; }
            public int Age { get; set; }
    
            
            public string Grade()
            {
                return "三年级";
            }
    
            public string Grade(string str)
            {
                return "三年级"+ str;
            }
    
            public string GetData(string str)
            {
                return str;
            }
    
    
            public static string StaticFun()
            {
                return "Static";
            }
            public static string StaticFun(string str)
            {
                return "Static"+str;
            }
    
            public string GetName<T>(T t)
            {
                return typeof(T).Name + t.ToString();
            }
    
            private string GetPrivateFun()
            {
                return "Private Fun";
            }
        }

    然后在另一个项目中,加载当前Student生成的Dll,来实现反射获取属性

     Assembly assembly = Assembly.Load("ReflectClass");
                    Type type = assembly.GetType("ReflectClass.Student");
                    foreach (var item in type.GetFields())
                    {
                        Console.WriteLine(item.Name);
                    }
    
                    foreach (var item in type.GetMethods())
                    {
                        Console.WriteLine(item.Name);
                    }
                    foreach (var item in type.GetProperties())
                    {
                        Console.WriteLine(item.Name);
                    }
                    foreach (var item in type.GetProperty("Name").GetCustomAttributes())
                    {
                        Console.WriteLine(item.ToString());
                    }
                    Console.ReadLine();

    简单工厂,配置切换代码逻辑

    通过反射,咱们可以实现一个简单工厂,来进行配置试的数据库切换,通过面向接口编程,来定义IDBTest接口和DBSqlHelper和DBOracleHelper

     public interface IDBTest
        {
            string Connection { get; set; }
    
            string Add();
    
            string Delete();
    
            string Update();
    
            string Select();
        }
     public class SqlHelper : IDBTest
        {
            public string Connection { get; set; }
    
            public string Add()
            {
                return "Sql Add";
            }
    
            public string Delete()
            {
                return "Sql Delete";
            }
    
            public string Select()
            {
                return "Sql Select";
            }
    
            public string Update()
            {
                return "Sql Update";
            }
        }
     public class OracleHelper : IDBTest
        {
            public string Connection { get; set; }
    
            public string Add()
            {
                return "Oracle Add";
            }
    
            public string Delete()
            {
                return "Oracle Delete";
            }
    
            public string Select()
            {
                return "Oracle Select";
            }
    
            public string Update()
            {
                return "Oracle Update";
            }
        }

    简单工厂

     public class SimplyFactory
        {
            private static string str = System.Configuration.ConfigurationManager.AppSettings["DBHelper"];
            private static string aStr = str.Split(',')[0];
            private static string tStr = str.Split(',')[1];
            public static T Instance<T>()
            {
                Assembly assembly = Assembly.Load(aStr);
                Type type = assembly.GetType(tStr);
                var helper = (T)Activator.CreateInstance(type);
                return helper;
            }
        }

    配置文件

      <appSettings>
        <add key="DBHelper" value="DBHelper,DBHelper.OracleHelper"/>
      </appSettings>

    主方法中,只需要通过以下代码就可以实现数据访问功能的实现,并且在需要求换数据请求逻辑的时候,更新配置文件即可,主函数不需要修改任何代码(面向借口编程)

    Console.WriteLine("配置文件简单工厂");
                    var helper = SimplyFactory.Instance<IDBTest>();
                    Console.WriteLine(helper.Add());
                    Console.WriteLine(helper.Delete());
                    Console.ReadLine();

    破坏单例

    通过反射还可以调用类中的私有构造函数来破坏单例模式

    public class SingleClass
        {
            private static SingleClass _singleClass = null;
    
            private SingleClass()
            {
                Console.WriteLine("singelClass 构造函数");
            } 
    
            static SingleClass()
            {
                _singleClass = new SingleClass();
            }
    
            public static SingleClass GetInstance()
            {
                return _singleClass;
            }
        }

    主函数调用

     Assembly assembly = Assembly.Load("ReflectClass");
                    Type type = assembly.GetType("ReflectClass.SingleClass");
                    var data1 = Activator.CreateInstance(type, true);
                    Console.ReadLine();

    实例化泛型类

    public class GenericClass<T,X,M>
        {
            public String Show(T t, X x, M m)
            {
                return typeof(T).Name + typeof(X).Name + typeof(M).Name;
            }
        }

    主函数调用(`3 表示是三个泛型参数的类)

     Assembly assembly = Assembly.Load("ReflectClass");
                    Type type = assembly.GetType("ReflectClass.GenericClass`3");
                    Type type1= type.MakeGenericType(typeof(string), typeof(int), typeof(DateTime));
                    var data = Activator.CreateInstance(type1);
                    Console.WriteLine();

    通过泛型来调用类的私有函数,重载函数,静态函数,泛型函数,(接着使用上面的Student类)

    Assembly assembly = Assembly.Load("ReflectClass");
                    Type type = assembly.GetType("ReflectClass.Student");
                    var data = Activator.CreateInstance(type);
                    var data1 = Activator.CreateInstance(type, new object[] { "张三", 12 });
                    //var data2 = Activator.CreateInstance(type, new object[] { 11, "张三"});
    
                    MethodInfo method = type.GetMethod("Grade",new Type[] { });
                    Console.WriteLine(method.Invoke(data1, null));
                    MethodInfo method1 = type.GetMethod("Grade", new Type[] {typeof(string)});
    
                    Console.WriteLine(method1.Invoke(data1, new object[] { "一个参数" }));
    
                    MethodInfo method2 = type.GetMethod("StaticFun", new Type[] { typeof(string)});
                    Console.WriteLine(method2.Invoke(null, new object[] { "静态函数一个参数"}));
    
                    MethodInfo method3 = type.GetMethod("GetName");
                    MethodInfo method3_1 = method3.MakeGenericMethod(typeof(string));
                    Console.WriteLine(method3_1.Invoke(data1, new object[] { "泛型" }));
    
                    MethodInfo method4 = type.GetMethod("GetPrivateFun",BindingFlags.Instance|BindingFlags.NonPublic);
                    Console.WriteLine(method4.Invoke(data1, null));
    
                    PropertyInfo proper = type.GetProperty("Name");
                    Console.WriteLine(proper.GetValue(data1));
                    proper.SetValue( data1,"李四");
                    Console.WriteLine(proper.GetValue(data1));
    
                    Console.ReadLine();

    反射的最大特点就是动态,代码不是写死的,而是可配置的,但是反射的使用会导致一定的性能损耗

  • 相关阅读:
    [LeetCode][JavaScript]Combination Sum II
    [LeetCode][JavaScript]Generate Parentheses
    [LeetCode][JavaScript]Contains Duplicate
    [LeetCode][JavaScript]Regular Expression Matching
    [LeetCode][JavaScript]Combination Sum
    [LeetCode][JavaScript]Two Sum
    Windows Live Writer的Markdown插件MarkdownInLiveWriter支持语法高亮了
    各种Markdown处理器的列表
    用ChooseALicense帮自己选一个开源license,然后用AddALicense给自己的github自动加上license文件
    遇到奇怪的C#/C/C++或者Java的bug可以去问问Coverity
  • 原文地址:https://www.cnblogs.com/notyourdog/p/10426398.html
Copyright © 2011-2022 走看看