C# 反射Reflection——反射反射程序员的快乐

一、什么是反射
反射Reflection:System.Reflection,是.Net Framework提供的一个帮助类库,可以读取并使用metadata。
反射是无处不在的,MVC-Asp.Net-ORM-IOC-AOP 几乎所有的框架都离不开反射
如下图是程序执行的过程,高级语言经过编译器编译得到dll/exe文件,这里的文件可以跨平台使用,编译后的文件中其实包括了metadata元数据(数据清单,描述了DLL/exe里面的各种信息)和IL(也是一种面向对象语言,但是不太好阅读)在经过CLR/JIT编译得到可以被计算机所执行的机器码。
C# 反射Reflection——反射反射程序员的快乐
二、反射的使用
一)反射动态加载程序集
            Assembly assembly1 = Assembly.LoadFrom(@"DB.MySql.dll");//当前路径
Assembly assembly2 = Assembly.LoadFile(@"D:\ruanmou\MyReflection\bin\Debug\DB.MySql.dll");//dll、exe文件完整路径
Assembly assembly3 = Assembly.Load(@"DB.MySql");//dll、exe名称 dll/exe需要拷贝至程序bin文件夹下

二)简单工厂生产对应实体

        /// <summary>
/// 简单工厂生产对应实体
/// </summary>
/// <returns></returns>
public static T CreateInstance<T>()
{
Assembly assembly = Assembly.Load(ConfigurationManager.AppSettings["DalDllName"]);//加载dll
Type dalType = assembly.GetType(ConfigurationManager.AppSettings["DalTypeName"]);//获取类型
return (T)Activator.CreateInstance(dalType);//创建对象
//var newType = dalType.MakeGenericType(typeof(T));//获取泛型类型
//return (T)Activator.CreateInstance(newType);创建泛型类型对象
}

三)常用方法

            Type[] types= assembly.GetTypes();//获取程序集所有类型
Type type= assembly.GetType("TypeName");//获取指定类型
MethodInfo[] methods= type.GetMethods();//获取所有方法
MethodInfo method= type.GetMethod("methodName");//获取指定方法
PropertyInfo[] propertys= type.GetProperties();//获取所有属性
PropertyInfo property = type.GetProperty("propertyName");//获取指定属性
FieldInfo[] fields= type.GetFields();//获取所有字段
FieldInfo field = type.GetField("fieldName");//获取指定字段
Attribute attribute = type.GetCustomAttribute(typeof(DisplayNameAttribute));//获取指定特性

反射调用多参数构造函数,方法

    /// <summary>
/// 反射测试类
/// </summary>
public class ReflectionTest
{
#region Identity
/// <summary>
/// 无参构造函数
/// </summary>
public ReflectionTest()
{
Console.WriteLine("这里是{0}无参数构造函数", this.GetType());
} /// <summary>
/// 带参数构造函数
/// </summary>
/// <param name="name"></param>
public ReflectionTest(string name)
{
Console.WriteLine("这里是{0} 有参数构造函数", this.GetType());
} public ReflectionTest(int id)
{
Console.WriteLine("这里是{0} 有参数构造函数", this.GetType());
}
#endregion #region Method
/// <summary>
/// 无参方法
/// </summary>
public void Show1()
{
Console.WriteLine("这里是{0}的Show1", this.GetType());
}
/// <summary>
/// 有参数方法
/// </summary>
/// <param name="id"></param>
public void Show2(int id)
{ Console.WriteLine("这里是{0}的Show2", this.GetType());
}
/// <summary>
/// 重载方法之一
/// </summary>
/// <param name="id"></param>
/// <param name="name"></param>
public void Show3(int id, string name)
{
Console.WriteLine("这里是{0}的Show3", this.GetType());
}
/// <summary>
/// 重载方法之二
/// </summary>
/// <param name="name"></param>
/// <param name="id"></param>
public void Show3(string name, int id)
{
Console.WriteLine("这里是{0}的Show3_2", this.GetType());
}
/// <summary>
/// 重载方法之三
/// </summary>
/// <param name="id"></param>
public void Show3(int id)
{ Console.WriteLine("这里是{0}的Show3_3", this.GetType());
}
/// <summary>
/// 重载方法之四
/// </summary>
/// <param name="name"></param>
public void Show3(string name)
{ Console.WriteLine("这里是{0}的Show3_4", this.GetType());
}
/// <summary>
/// 重载方法之五
/// </summary>
public void Show3()
{ Console.WriteLine("这里是{0}的Show3_1", this.GetType());
}
/// <summary>
/// 私有方法
/// </summary>
/// <param name="name"></param>
private void Show4(string name)
{
Console.WriteLine("这里是{0}的Show4", this.GetType());
}
/// <summary>
/// 静态方法
/// </summary>
/// <param name="name"></param>
public static void Show5(string name)
{
Console.WriteLine("这里是{0}的Show5", typeof(ReflectionTest));
}
#endregion
}
                Assembly assembly = Assembly.Load("Ruanmou.DB.SqlServer");
Type type = assembly.GetType("Ruanmou.DB.SqlServer.ReflectionTest");
object oTest = Activator.CreateInstance(type);//反射调用无参数构造函数
object oTest2 = Activator.CreateInstance(type, new object[] { });//反射调用一个int类型参数构造函数
foreach (var method in type.GetMethods())
{
Console.WriteLine(method.Name);
foreach (var parameter in method.GetParameters())//获取方法参数
{
Console.WriteLine($"{parameter.Name} {parameter.ParameterType}");
}
}
{
ReflectionTest reflection = new ReflectionTest();
reflection.Show1();
}
{
MethodInfo method = type.GetMethod("Show1");
//if()
method.Invoke(oTest, null);//oTest调用无参数方法
}
{
MethodInfo method = type.GetMethod("Show2");
method.Invoke(oTest, new object[] { });//oTest调用一个int类型参数方法
}
{
MethodInfo method = type.GetMethod("Show3", new Type[] { });
method.Invoke(oTest, null);//oTest调用无参数重载方法
}
{
MethodInfo method = type.GetMethod("Show3", new Type[] { typeof(int) });
method.Invoke(oTest, new object[] { });//oTest调用一个int类型参数重载方法
} {
MethodInfo method = type.GetMethod("Show5");
method.Invoke(oTest, new object[] { "String" });//静态方法实例可以要
}
{
MethodInfo method = type.GetMethod("Show5");
method.Invoke(null, new object[] { "string" });//静态方法实例也可以不要
}
                    var method = type.GetMethod("Show4", BindingFlags.Instance | BindingFlags.NonPublic);
method.Invoke(oTest, new object[] { "私有方法" });

反射调用私有方法

反射调用泛型方法、泛型类

    public class GenericClass<T, W, X>
{
public void Show(T t, W w, X x)
{
Console.WriteLine("t.type={0},w.type={1},x.type={2}", t.GetType().Name, w.GetType().Name, x.GetType().Name);
}
} public class GenericMethod
{
public void Show<T, W, X>(T t, W w, X x)
{
Console.WriteLine("t.type={0},w.type={1},x.type={2}", t.GetType().Name, w.GetType().Name, x.GetType().Name);
}
} public class GenericDouble<T>
{
public void Show<W, X>(T t, W w, X x)
{
Console.WriteLine("t.type={0},w.type={1},x.type={2}", t.GetType().Name, w.GetType().Name, x.GetType().Name);
}
}
               {
Console.WriteLine("********************GenericMethod********************");
Assembly assembly = Assembly.Load("Ruanmou.DB.SqlServer");
Type type = assembly.GetType("Ruanmou.DB.SqlServer.GenericMethod");
object oGeneric = Activator.CreateInstance(type);
//foreach (var item in type.GetMethods())
//{
// Console.WriteLine(item.Name);
//}
MethodInfo method = type.GetMethod("Show");
var methodNew = method.MakeGenericMethod(new Type[] { typeof(int), typeof(string), typeof(DateTime) });
object oReturn = methodNew.Invoke(oGeneric, new object[] { , "test", DateTime.Now });
}
{
Console.WriteLine("********************GenericMethod+GenericClass********************");
Assembly assembly = Assembly.Load("Ruanmou.DB.SqlServer");
Type type = assembly.GetType("Ruanmou.DB.SqlServer.GenericDouble`1").MakeGenericType(typeof(int));
object oObject = Activator.CreateInstance(type);
MethodInfo method = type.GetMethod("Show").MakeGenericMethod(typeof(string), typeof(DateTime));
method.Invoke(oObject, new object[] { , "teat", DateTime.Now }); }

反射破坏单例

    /// <summary>
/// 单例模式:类,能保证在整个进程中只有一个实例
/// </summary>
public sealed class Singleton
{
private static Singleton _Singleton = null;
private Singleton()
{
Console.WriteLine("Singleton被构造");
} static Singleton()
{
_Singleton = new Singleton();
} public static Singleton GetInstance()
{
return _Singleton;
}
}
                  {

                    Console.WriteLine("********************Singleton********************");
Singleton singleton1 = Singleton.GetInstance(); //new Singleton();
Singleton singleton2 = Singleton.GetInstance();
Singleton singleton3 = Singleton.GetInstance();
Singleton singleton4 = Singleton.GetInstance();
Singleton singleton5 = Singleton.GetInstance();
Console.WriteLine($"{object.ReferenceEquals(singleton1, singleton5)}"); //反射破坏单例---就是发射调用私有构造函数
Assembly assembly = Assembly.Load("Ruanmou.DB.SqlServer");
Type type = assembly.GetType("Ruanmou.DB.SqlServer.Singleton");
Singleton singletonA = (Singleton)Activator.CreateInstance(type, true);
Singleton singletonB = (Singleton)Activator.CreateInstance(type, true);
Singleton singletonC = (Singleton)Activator.CreateInstance(type, true);
Singleton singletonD = (Singleton)Activator.CreateInstance(type, true);
Console.WriteLine($"{object.ReferenceEquals(singletonA, singletonD)}");
}

本文参考文档:

https://www.cnblogs.com/loverwangshan/p/9883243.html;

微软文档地址:

.NET Framework 中的反射:https://docs.microsoft.com/zh-cn/dotnet/framework/reflection-and-codedom/reflection;

System.Reflection Namespace:https://docs.microsoft.com/zh-cn/dotnet/api/system.reflection?view=netframework-4.7.2;

Type Class:https://docs.microsoft.com/zh-cn/dotnet/api/system.type?view=netframework-4.7.2;

上一篇:[C#][控件]列表控件listbox(一)


下一篇:.NET 反射(Reflection)