反射、元数据、动态编程
1、定义
MicroSoft Docs 给出的定义:
反射提供描述程序集、模块和类型的对象(

[图片来自 《C# 7.0 本质论》]
元数据:C# 编写的程序编译成一个程序集,程序集会包含元数据、编译代码和资源。 元数据包含内容:
-
程序或类库中每一个类型的描述;
-
清单信息,包括与程序本身有关的数据,以及它依赖的库;
-
在代码中嵌入的自定义特性,提供与特性所修饰的构造有关的额外信息。
反射:在运行时检查并使用元数据和编译代码的操作称为反射。
一个程序集包含的内容:

[图片来自 《C# 7.0 核心技术指南》]
2、用途
反射在以下情况下很有用:
-
需要访问程序元数据中的特性时。
-
检查和实例化程序集中的类型。
-
在运行时构建新类型。使用System.Reflection.Emit中的类。
-
执行后期绑定,访问在运行时创建的在类型上的方法。
3、Type信息:
当反射提出请求时,公共语言运行时为已加载的类型创建 Type 。 可使用 Type 对象的方法、字段、属性和嵌套类来查找该类型的任何信息。
获取type:
int i = 12; Console.WriteLine(i.GetType()); Console.WriteLine(typeof(int));
typeof()静态方法,从类型获取type;
GetType()从实例化对象获取type;
结合程序集来使用:
//结合程序集来使用 Assembly val = Assembly.LoadFrom(@"E:\Demo\IsInAsTest\bin\Debug\netcoreapp3.1\IsInAsTest.dll"); Console.WriteLine(val); //完全限定程序集中类型"IsInAsTest.Circle" Type type = val.GetType("IsInAsTest.Circle"); Console.WriteLine($"type:{type}"); Type[] types = val.GetTypes(); Console.WriteLine(types); //循环打印程序集中的类型 foreach (var item in types) { Console.WriteLine(item); }
运行结果如下:

列出类的构造函数ConstructorInfo,使用
4、反射在泛型上的使用
直接拿官网demo对比
Type d1 = typeof(Dictionary<,>); Dictionary<string, Example> d2 = new Dictionary<string, Example>(); Example.DisplayGenericType(d1); Example.DisplayGenericType(d2.GetType()); Type[] typeArgus = { typeof(string), typeof(Example) }; Type constructed = d1.MakeGenericType(typeArgus); Example.DisplayGenericType(constructed); object o = Activator.CreateInstance(constructed); Console.WriteLine("\r\nCompare types obtained by different methods:"); Console.WriteLine(" Are the constructed types equal? {0}", (d2.GetType() == constructed)); Console.WriteLine(" Are the generic definitions equal? {0}", (d1 == constructed.GetGenericTypeDefinition())); Example.DisplayGenericType(typeof(Test<>));
public class Example { // The following method displays information about a generic // type. public static void DisplayGenericType(Type t) { Console.WriteLine("\r\n {0}", t); Console.WriteLine(" Is this a generic type? {0}", t.IsGenericType); Console.WriteLine(" Is this a generic type definition? {0}", t.IsGenericTypeDefinition); // Get the generic type parameters or type arguments. Type[] typeParameters = t.GetGenericArguments(); Console.WriteLine(" List {0} type arguments:", typeParameters.Length); foreach (Type tParam in typeParameters) { if (tParam.IsGenericParameter) { DisplayGenericParameter(tParam); } else { Console.WriteLine(" Type argument: {0}", tParam); } } } // The following method displays information about a generic // type parameter. Generic type parameters are represented by // instances of System.Type, just like ordinary types. public static void DisplayGenericParameter(Type tp) { Console.WriteLine(" Type parameter: {0} position {1}", tp.Name, tp.GenericParameterPosition); Type classConstraint = null; foreach (Type iConstraint in tp.GetGenericParameterConstraints()) { if (iConstraint.IsInterface) { Console.WriteLine(" Interface constraint: {0}", iConstraint); } } if (classConstraint != null) { Console.WriteLine(" Base type constraint: {0}", tp.BaseType); } else { Console.WriteLine(" Base type constraint: None"); } GenericParameterAttributes sConstraints = tp.GenericParameterAttributes & GenericParameterAttributes.SpecialConstraintMask; if (sConstraints == GenericParameterAttributes.None) { Console.WriteLine(" No special constraints."); } else { if (GenericParameterAttributes.None != (sConstraints & GenericParameterAttributes.DefaultConstructorConstraint)) { Console.WriteLine(" Must have a parameterless constructor."); } if (GenericParameterAttributes.None != (sConstraints & GenericParameterAttributes.ReferenceTypeConstraint)) { Console.WriteLine(" Must be a reference type."); } if (GenericParameterAttributes.None != (sConstraints & GenericParameterAttributes.NotNullableValueTypeConstraint)) { Console.WriteLine(" Must be a non-nullable value type."); } } } }
打印信息如下:
System.Collections.Generic.Dictionary`2[TKey,TValue] Is this a generic type? True Is this a generic type definition? True List 2 type arguments: Type parameter: TKey position 0 Base type constraint: None No special constraints. Type parameter: TValue position 1 Base type constraint: None No special constraints. System.Collections.Generic.Dictionary`2[System.String,ReflectionTest.Example] Is this a generic type? True Is this a generic type definition? False List 2 type arguments: Type argument: System.String Type argument: ReflectionTest.Example System.Collections.Generic.Dictionary`2[System.String,ReflectionTest.Example] Is this a generic type? True Is this a generic type definition? False List 2 type arguments: Type argument: System.String Type argument: ReflectionTest.Example Compare types obtained by different methods: Are the constructed types equal? True Are the generic definitions equal? True ReflectionTest.Test`1[T] Is this a generic type? True Is this a generic type definition? True List 1 type arguments: Type parameter: T position 0 Interface constraint: ReflectionTest.ITestArgument Base type constraint: None Must have a parameterless constructor.
参考资料:
痴者工良博客:https://www.cnblogs.com/whuanle/p/12115505.html
浙公网安备 33010602011771号