本文详细介绍了C#中的反射机制,包括Assembly类的使用,如加载程序集、获取类型等;Type类的各种API,如获取成员、创建类型实例;MethodInfo类的函数信息,如调用方法;PropertyInfo和FieldInfo类用于处理属性和字段;以及BindingFlags枚举在检索条件中的作用。此外,还提供了实例代码展示如何通过反射调用方法、属性和字段,以及如何处理泛型成员。
摘要由CSDN通过智能技术生成
类名
|
实例方式
|
用途
|
Assembly
程序集类
|
Assembly <Name> = Assembly.loadFrom("Path");
|
左侧代码调用了Assembly类的静态函数loadFrom通过查找文件地址返回程序集对象(Assembly对象)
|
Type
类型类
|
Type <Name> = <AssemblyObj>.GetType("Type Name");
|
左侧代码调用了Assembly类的函数GetType通过查找成员名返回Type对象
|
MethodInfo
函数信息类
|
MethodInfo <Name> = <TypeObj>.GetMethod("FuncName");
|
左侧代码调用了Type类的函数GetMethod通过查找函数名返回MethodInfo对象
|
PropertyInfo
属性信息类
|
PropertyInfo <Name> = <TypeObj>.GetProperty("PropertyName");
|
左侧代码调用了Type类的函数GetProperty通过查找属性名返回PropertyInfo对象
|
FieldInfo
字段信息类
|
FieldInfo <Name>=<TypeObj>.GetField("Field Name");
|
左侧代码调用了Type类的函数GetField通过查找属性名返回FieldInfo对象
|
BindingFlags
筛选标志
|
枚举类型
|
通常用于检索条件/调用标识
|
专有名词解析
|
Assembly类型解析
using Reflection;//用于引入反射包
/* Assembly常用API
//通过路径返回程序集对象
Assembly.LoadFrom("Path"); return:AssemblyObj;
//返回程序集对象里的所有类型(类/结构体... ...)
<AssemblyObj>.GetTypes(); return:TypeObj[];
//通过类型名字(TypeName)进行查找然后返回
<AssemblyObj>.GetType("TypeName"); return:TypeObj;
-->:<AssemblyObj>.GetType("TypeName`int");//用于查找泛型类 其中[`int]:`为必带的,int为泛型的数量
-->:TypeName的结构必须是 NameSpace.Class
//返回包含程序入口点的程序集
Assembly.GetEntryAssembly(); return:AssemblyObj;
//返回当前代码执行的程序集
Assembly.GetExecutingAssembly(); return:AssemblyObj;
//返回当前代码执行的程序集
<AssemblyObj>.GetExecutingAssembly(); return:AssemblyObj;
//将类型实例化成具体的对象
<AssemblyObj>.CreateInstance("TypeName“); return:Object; TypeName:命名空间.类型名
/* Assembly常用成员属性
//获取程序集的完全限定名
<AssemblyObj>.FullName;+ return:String;
//获取程序集的文件绝对路径
<AssemblyObj>.Location; return:String;
//获取程序集合入口方法
<AssemblyObj>.EntryPoint; return:MethodInfo;
//判断程序集是否在全局缓存中
<AssemblyObj>.GlobalAssemblyCache; return:Bool;
//获取程序集的代码库位置 不带转义符
<AssemblyObj>.CodeBase; return:String;
//获取程序集的代码库位置 带转义符
<AssemblyObj>.EscapedCodeBase; return:String;
//获取程序集的CLR版本
<AssemblyObj>.ImageRuntimeVersion; return:String;
//获取程序集的清单模块
<AssemblyObj>.MannifestModule; return:RuntimeModule;
//判断程序集是否只能用于反射上下文
<AssemblyObj>.ReflectionOnly; return:Bool;
//判断程序集是否是动态程序集
<AssemblyObj>.IsDynamic; return:Bool;
Type类型解析
using System;//Type类型必备的包
/*Type类型常用API
//返回Type类型 对一个类型做两次GetType的返回值不一样
<TypeObj>.GetType(Object); 第一次return:Type; 第二次return:RuntimeType;
//返回Type的枚举类型 其实就是方便识别的类型比如String/Int等
<TypeObj>.GetTypeCode(); return:TypeCode;
//用于直接调用成员
<TypeObj>.InvokeMember("MemberName",<BindingFlags.Enum>,<Binder>,<InstanceObject>,new object(<args>...));
-->:MemberName:成员名 主要看后面筛选规则是什么
-->:BindingFlags.Enum:BindingFlags枚举类型,用于限制查找条件
-->:InvokeMember除了条件BindingFlags以外必须带有一个特殊的BindIngFlags
-->:InvokeMember去实例对象时除了BindingFlags.CreateInstance以外不要带其他BindingFlags
-->:Binder:很高级我不会,所以一般都填null
-->:InstanceObject:具体调用这个函数的对象,若是静态函数则填null
-->:new object(<args>...):调用函数的传参 比如调用一个func(int temp_1,string temp_2)的函数
-->:则为 new object(Int,String);
//判断Obj是否是TypeObj类的实例化对象
<TypeObj>.IsInstanceOfType(Obj); return:Bool;
//判断TypeObj2是否是TypeObj的 派生类(子类)
<TypeObj>.IsSubclassof(TypeObj2); return:Bool;
//与特性相关 判断类型是否拥有特性 <AttributeClass Class>:特性类 <Bool Inherit>:true则查找继承链,false不查找
<TypeObj>.IsDefined( typeof(<AttributeClass Class>) , <Bool Inherit>); return:Bool;
//Make方法汇总 用于创建Type对象
<TypeObj>.MakeArrayType(Int); Int可选; return:Type; //创建一个TypeObj的数组类型
<TypeObj>.MakeGenericType(typeof(<类型>)...); return:Type //创建一个泛型类型的Type对象
<TypeObj>.MakeByRefType(); return:Type //创建一个引用类型的Type对象
//Get函数方法汇总 用于获取内容(成员)
<TypeObj>.GetElementType(); return:Type; //若TypeObj是数组类型,则返回数组的元素类型
<TypeObj>.GetField("FieldName"); return:FieldInfo; //通过FieldName获取字段
-->:<TypeObj>.GetField("FieldName",<BindingFlags.Enum>);
-->:<TypeObj>.GetFields(); return:FieldInfo[]; //获取所有字段
<TypeObj>.GetInterface("InterFaceName"); return:Type; //通过检索InterFaceName获取类型所实现的接口
-->:<TypeObj>.GetInterfaces(); return:Type[]; //获取类型所实现的所有接口
<TypeObj>.GetMethod("MethodName"); return:MethodInfo; //通过MethodName获取函数
-->:<TypeObj>.GetMethod("MethodName",new object(<Args>...));//带参数的获取方法
-->:<TypeObj>.GetMethod("MethodName",<BindingFlags.Enum>,new object(<Args>...));
-->:<TypeObj>.GetMethods(); return:MethodInfo[]; //获取所有函数
//获取静态的非公开的函数
-->:<TypeObj>GetMethod("MethodName",BindingFlags.Static|BindingFlags.NonPublic);
<TypeObj>.GetProperty("PropertyName"); return:PropertyInfo; //通过PropertyName获取属性
-->:<TypeObj>.GetProperty("PropertyName",<BindingFlags.Enum>);
-->:<TypeObj>.GetProperties(); return:PropertyInfo[]; //获取所有Property组成的数组
<TypeObj>.GetConstructor(new Type[]{typeof(<类型1>)...}); return:ConstructorInfo;
//根据参数传类型 返回构造函数
-->:<TypeObj>.GetConstructors(); return:ConstructorInfo[]; //返回所有构造函数组成的数组
<TypeObj>.GetCustomAttributes(typeof(<AttributeClass Class>,<Bool inherit>));
//return:object 可以通过as转换为类
//查找当前类型所加载的所有指定特性 <AttributeClass>:指定特性 <Bool Inherit>:是否查找根目录
//查找到的同时将其构造出来
/*Type类型常用属性
<TypeObj>.AssemblyQualifedName; //获取类型在程序集的完全限定名
<TypeObj>.Assembly; //获取包含类型的程序集对象本身
<TypeObj>.Attributes; //获取类型的自定义特性
<TypeObj>.BaseType; //获取类型的基(父)类型
<TypeObj>.ContainsGemericParameters; //判断类型是否存在未指定的泛型参数
<TypeObj>.DeclaringMethod; //获取声明类型的方法
<TypeObj>.DeclaringType; //获取声明类型的类型\
<TypeObj>.FullName; //获取类型的完全限定名
<TypeObj>.GenericParameterAttributes; //获取泛型类型参数的特性
<TypeObj>.GenericParameterPosition; //获取泛型类型参数在类型参数列表中的位置
<TypeObj>.GUID; //获取类型的GUID
<TypeObj>.HasElementType; //判断类型是否是数组/指针/引用
//Is属性汇总 return:Bool
<TypeObj>.IsAbstract; //判断是否为抽象的
<TypeObj>.IsArray; //判断是否为数组
<TypeObj>.IsByRef; //判断是否为引用类型
<TypeObj>.IsClass; //判断是否为类或者委托(即:不是接口或者值类型等)
<TypeObj>.IsEnum; //判断是否为枚举类型
<TypeObj>.IsGenericParameter; //判断是否为泛型类型参数
<TypeObj>.IsGenericType; //判断是否为泛型类型
<TypeObj>.IsInterface; //判断是否为接口
<TypeObj>.IsNested; //判断是否为嵌套类型
<TypeObj>.IsNotPublic; //判断是否不是公共的 且 并不在同一程序集中
<TypeObj>.Isprimitive; //判断是否为基元类型
<TypeObj>.IsPublic; //判断是否为公共类型
<TypeObj>.IsSealed; //判断是否为密封类型 带关键词:Sealed的类,指无法被继承
<TypeObj>.IsSerializable; //判断是否为可序列化的
<TypeObj>.IsValueType; //判断是否为值类型
//不常用的
<TypeObj>.IsAutoClass; //判断是否为自动类
<TypeObj>.IsAutoLayout; //判断是否为自动布局的
<TypeObj>.IsAnsiClass; //判断是否为使用ANSI标准的类
<TypeObj>.IsContextful; //判断是否为上下文相关的泛型类型
<TypeObj>.IsImport; //判断是否为COM类型库导入的类型
<TypeObj>.IsLayoutSequential; //判断是否为顺序布局
<TypeObj>.IsMarshalByRef; //判断是否由MarshalByRefObject派生的类
<TypeObj>.IsSecuritySafeCritical;//判断是否为安全关键类型
<TypeObj>.IsSpecialName; //判断是否存在特殊名称
<TypeObj>.IsUnicodeClass; //判断是否满足Unicode标准的类
<TypeObj>.IsGenericTypeDefinition;//判断是否为泛型类型的定义 即:typeof(List<>)而非typeof(List<类型>)
<TypeObj>.IsConstructedGenericType;//判断是否为已构造的泛型类型 即:typeof(List<类型>)而非typeof(List<>)
<TypeObj>.IsVisible; //判断是否为公共或者嵌套类型 一个类型是否对当前程序集可见
MethodInfo类型解析
/*MethodInfo解析 <MethodInfo>转换<Info>
//MethodInfo属性
<Info>.MemberType; //获取MemberType值,用于指示这个成员是方法
<Info>.MethodHandle; //获取RuntimeMethodHandle,用于表示内部的元数据类型
<Info>.MethodImplementationFlags;//获取MethodImplAttributes值,该值指示此方法的实现标志
<Info>.Name; //此方法的名词
<Info>.ReflectionType; //获取此方法的类对象
<Info>.ReturnType; //获取方法的返回类型
<Info>.ReturnTypeCustomAttributes;//获取包含返回类型的自定义属性
<Info>.CallingConventionl //获取此方法的调用约定
//Is判断内容
<Info>.IsAbstract; //判断是否为抽象的
<Info>.IsAssembly; //判断是否只能由内部程序集访问
<Info>.IsConstructor; //判断是否为构造函数
<Info>.IsFamliy; //判断是否只能有类或者子类的对象调用
<Info>.IsFamliyAndAssembly; //判断既属于程序集又属于类的对象调用
<Info>.IsFamliyAndAssembly; //判断是否属于程序集或者指定类的对象调用
<Info>.IsFinal; //判断是否为Final方法
<Info>.IsGenericMethod; //判断是否为泛型类型
<Info>.IsHideBySig; //判断是否隐藏继承的成员
<Info>.IsPrivate; //判断是否为私有函数
<Info>.IsPublic; //判断是否为共有函数
<Info>.IsSpecialName; //判断是否存在特殊名称
<Info>.IsStatic; //判断是否静态方法
<Info>.IsVirtual; //判断是否为虚方法
/*MethodInfo API函数
<Info>.GetParameters(); //获取方法的参数列表 只能获取一个函数 若存在多个函数则会报错
<Info>.GetCustomAttribute(type(<Attribute>)); //获取特性
<Info>.Invoke(Object,new object[]{Parameter... ...}); //调用函数 Invoke(具体的对象,new object[]{参数... ...})
<Info>.Invoke(null,new object[]{Parameter... ...}); //调用静态函数
<Info>.MakeGenericMethods(typeof(<类型1>)...); return:MethodInfo; //获取到方法后可以用这个调用泛型方法
FieldInfo解析
/*FieldInfo属性 解析 <FieldInfo>简写<Info>
<Info>.CustomAttributes; //获取一个包含当前字段的自定义属性的集合
<Info>.Name; //获取字段的名称。
<Info>.FieldType; //获取字段的类型。
//Is判断内容
<Info>.IsStatic; //获取一个值,该值指示字段是否为静态字段。
<Info>.IsPublic; //获取一个值,该值指示字段是否为公共字段。
<Info>.IsPrivate; //获取一个值,该值指示字段是否为私有字段。
<Info>.IsFamily; //获取一个值,该值指示字段是否为受保护的字段。
<Info>.IsAssembly; //获取一个值,该值指示字段是否为内部字段。
<Info>.IsFamilyOrAssembly; //获取一个值,该值指示字段是否为受保护的内部字段。
<Info>.IsInitOnly; //获取一个值,该值指示字段是否为只读字段。
<Info>.IsLiteral; //获取一个值,该值指示字段是否为常量字段。
<Info>.IsNotSerialized; //获取一个值,该值指示字段是否不应序列化。
<Info>.IsPinvokeImpl; //获取一个值,该值指示字段是否为 P/Invoke 实现。
<Info>.IsSpecialName; //获取一个值,该值指示字段是否具有特殊名称。
/*FieldInfo API
<Info>.IsDefined(Type attributeType, bool inherit); //获取一个值,该值指示是否定义了指定类型的特性
<Info>.GetValue(<Object>); //获取字段里的值
<Info>.SetValue(<Object>,<Value>); //向字段内写入值
PropertyInfo解析
/*PropertyInfo解析 <propertyInfo>简写<Info>
//PropertyInfo属性
Property.PropeytyType; //获取属性的属性
Property.IsDefined(<AttributeType>,<Bool>); //是否将一个或多个特性应用于此成员
//PropetyInfo函数
<Info>.GetValue(<Object>); //调用属性的Get方法
<Info>.SetValue(<Object>,<Value>); //调用属性的Set方法
<Info>.GetCustomAttributes(<Bool>); //获取属性上定义的特性 <Bool>为True则搜索此成员的继承链以查找这些属特性 False只查找自身的
<Info>.GetCustomAttributes(typeof(<Attribute>),<Bool>); //查找特定特性
BindingFlags解析
//BindingFlags是一个枚举类型
//限制筛选规则
BindingFlags.Default; //默认模式
BindingFlags.IgnoreCase; //无视大小写
BindingFlags.IgnoreReturn; //忽略函数返回值
BindingFlags.Instance; //包含实例成员
BindingFlags.NonPublic; //包含非公共成员
BindingFlags.Public; //公共成员
BindingFlags.Static; //静态成员
BindingFlags.FlattenHierarchy; //搜索类型层次结构中的父级 ?我不理解
//调用筛选规则
BindingFlags.PutDispProperty; //分配给Idispatch::Invoke的属性
BindingFlags.PutRefDispProperty; //分配给IDispatch::Invoke的ref属性
BindingFlags.SetField; //Set字段
BindingFlags.SetProperty; //Set属性
BindingFlags.GetField; //Get字段
BindingFlags.GetProperty; //Get属性属性
BindingFlags.ExactBinding; //确切的绑定:只有在名称、参数类型和修饰符都完全匹配时才会返回成员
BindingFlags.InvokeMethod; //若使用Type.InvokeMethod调用函数时,则添加这个筛选规则
BindingFlags.CreateInstance; //用于创建实例
/*常用组合搭配
Instance | Public | NonPublic:指定所有实例成员。
Static | Public | NonPublic:指定所有静态成员。
FlattenHierarchy | Public | Instance:指定搜索类型层次结构中的公共实例成员和父级。
FlattenHierarchy | Public | Static:指定搜索类型层次结构中的公共静态成员和父级。
FlattenHierarchy | Public | Instance | DeclaredOnly:指定搜索类型层次结构中的公共实例成员和父级,但仅在当前类型中查找成员,而不搜索基类型。
专有名词解析
/*基元类型
bool:表示布尔值。
byte:表示8位无符号整数。
sbyte:表示8位有符号整数。
char:表示16位 Unicode 字符。
decimal:表示高精度小数。
double:表示64位浮点数。
float:表示32位浮点数。
int:表示32位有符号整数。
uint:表示32位无符号整数。
long:表示64位有符号整数。
ulong:表示64位无符号整数。
short:表示16位有符号整数。
ushort:表示16位无符号整数
/*实例成员
实例成员是指只能通过类的实例来访问的成员,而不能通过类名来访问。
实例成员包括实例字段、实例属性、实例方法和实例事件。
可以使用BindingFlags.Instance标志来获取实例成员。
int <name> = <Value>;
这就是一个字段
int <PropertyName>={
set{代码块}
get{代码块}
这就是一个属性
先创建一个文件里面包含两个类,随后将其生成为dll文件
namespace{
//写一个接口IUtil 权限为public 拥有一个函数String Func()
public interface IUtil
string TestFunc();
//再写一个UtilPackage类,实现了IUtil
public class UtilPackage:IUtil
public string TestFunc()
Console.WriteLine("TestFunc无参");
return "TestFUnc";
此时将其文件路径复制,博主这边dll文件路径位置为F:\C#学习\C# item\Util\bin\Debug\Util.dll
using System;
using Reflection;//反射必备的命名空间
namespace
internal class Program{
private static void Main(string[] args)
//利用Assembly
Assembly assembly = Assembly.LoadFrom(@"F:\C#学习\C# item\Util\bin\Debug\Util.dll");
引入Reflection反射包;using Reflection;
第一阶段:利用反射调用dll文件里的函数TestFunc
using System;
using System.Reflection;//反射必备的命名空间
namespace
internal class Program{
private static void Main(string[] args)
//通过Assembly的API:LoadFrom获取到程序集对象
Assembly utilAss = Assembly.LoadFrom(@"F:\C#学习\C# item\Util\bin\Debug\Util.dll");
//通过Assembly的API:GetType获取UtilPackage的类型Type
Type utilPackageType = utilAss.GetType("Util.UtilPackage");
//通过Assembly里的API:CreateInstance("MemberName");去实例一个对象
object utilPackageObj = utilAss.CreateInstance("Util.UtilPackage");
//对于这一步也可以用Activator.CreateInstance(<Type>)去创建对象
//例如:object UtilPackageObj = Acitivator.CreateInstance(utilPackageType);
//通过Type里的API:GetMethod("MethodName")获取到了具体的函数对象
MethodInfo textFunc = utilPackageType.GetMethod("TestFunc");
//调用MethodInfo类的API:Invoke(<Object>,<Parameter>)去执行函数
//MethodInfo.Invoke(<实例对象>,<参数>);注意参数要用new object去传输
testFunc.Invoke(utilPackageObj, new object[] { });
当读者去执行这块代码时,输出的结果为:TestFunc无参
第二阶段:利用反射调用重载方法
将原UtilPackage小做修改
namespace Util{
//写一个接口IUtil 权限为public 拥有一个函数String Func()
public interface IUtil
string TestFunc();
//再写一个UtilPackage类,实现了IUtil
public class UtilPackage:IUtil
//原TestFunc
public string TestFunc()
Console.WriteLine("TestFunc无参");
return "TestFUnc";
//重载TestFunc函数
public string TestFunc(String temp_i)
Console.WriteLine("TestFunc|参数1:String="+temp_i);
return "TestFUnc";
//重载TestFunc函数
public string TestFunc(String temp_i,int temp_j)
Console.WriteLine("TestFunc|参数1:String="+temp_i+"|参数2:int="+temp_j);
return "TestFUnc";
回到主要函数Main来
using System;
using System.Reflection;//反射必备的命名空间
namespace
internal class Program{
private static void Main(string[] args)
//通过Assembly的API:LoadFrom获取到程序集对象
Assembly utilAss = Assembly.LoadFrom(@"F:\C#学习\C# item\Util\bin\Debug\Util.dll");
//通过Assembly的API:GetType获取UtilPackage的类型Type
Type utilPackageType = utilAss.GetType("Util.UtilPackage");
//通过Assembly里的API:CreateInstance("MemberName");去实例一个对象
object utilPackageObj = utilAss.CreateInstance("Util.UtilPackage");
//对于这一步也可以用Activator.CreateInstance(<Type>)去创建对象
//例如:object UtilPackageObj = Acitivator.CreateInstance(utilPackageType);
//-------------------------------------------------------分割符
//通过Type里的API:GetMethod("MethodName",<ParameterType>)获取到了具体的函数对象
//这里才用GetMethod的重载方法
MethodInfo testFunc1 = utilPackageType.GetMethod("TestFunc", new Type[] {});
MethodInfo testFunc2 = utilPackageType.GetMethod("TestFunc", new Type[] {typeof(string)});
MethodInfo testFunc3 = utilPackageType.GetMethod("TestFunc", new Type[] {typeof(string),typeof(int)});
//MethodInfo.Invoke(<实例对象>,<参数>);注意参数要用new object去传输
testFunc1.Invoke(utilPackageObj, new object[] { });
testFunc2.Invoke(utilPackageObj, new object[] {"DarkSKL"});
testFunc3.Invoke(utilPackageObj, new object[] {"DarkSKL",18});
/*//当读者去执行这篇代码时,运行结果为:
TestFunc无参
TestFunc|参数1:String=DarkSKL
TestFunc|参数1:String=DarkSKL|参数2:int=18
第三阶段:通过反射调用属性以及字段,包含私有如何获取
将原UtilPackage小做修改
namespace Util
public class UtilPackage : IUtil
//定义了一个name字段
private string name = "DarkSKL";
//以及一个只有get方法的Name属性
public string Name
get { return name; }
public string TestFunc()
Console.WriteLine("TestFunc无参");
return "TestFUnc";
回到主要函数Main来
using System;
using System.Reflection;//反射必备的命名空间
namespace Util
internal class Program{
private static void Main(string[] args)
//通过Assembly的API:LoadFrom获取到程序集对象
Assembly utilAss = Assembly.LoadFrom(@"F:\C#学习\C# item\Util\bin\Debug\Util.dll");
//通过Assembly的API:GetType获取UtilPackage的类型Type
Type utilPackageType = utilAss.GetType("Util.UtilPackage");
//通过Assembly里的API:CreateInstance("MemberName");去实例一个对象
object utilPackageObj = utilAss.CreateInstance("Util.UtilPackage");
//对于这一步也可以用Activator.CreateInstance(<Type>)去创建对象
//例如:object UtilPackageObj = Acitivator.CreateInstance(utilPackageType);
//-------------------------------------------------------分割符
//注意这串代码会找不到字段name:FieldInfo nameField = utilPackageType.GetField("name");
//如果要获取私有的,则需要用到重载方法GetField("FieldName",<BindingFlags.Enum>)
FieldInfo nameField = utilPackageType.GetField("name",BindingFlags.NonPublic|BindingFlags.Instance);
//通过Type类的API:GetProperty获得属性对象
PropertyInfo nameProperty = utilPackageType.GetProperty("Name");
//调用FieldInfo得API:GetValue(<Object>)获取值内容
Console.WriteLine("name值为:"+nameField.GetValue(utilPackageObj));
//调用FieldInfo得API:GetValue(<Object>)获取值内容
Console.WriteLine("name值为:"+nameProperty.GetValue(utilPackageObj));
当读者执行完代码时,输出结果为:
name值为:DarkSKL
name值为:DarkSKL
第四阶段:通过反射调用泛型成员
将原UtilPackage小做修改
namespace Util
//类存在一个泛型参数<T>
public class UtilPackage<T> : IUtil
//用于保存自身类型
private Type utilGenericType = typeof(T);
//用于返回自身类型
public Type UtilGenericType
get { return utilGenericType; }`
//利用<T>声明一个字段value
private T value;
//利用属性返回value
public T Value
set { this.value = value;}
get { return value; }
//重写的IUtil接口的方法
public string TestFunc()
Console.WriteLine("TextFunc");
return "TestFunc";
//重载TextFunc,定义了一个泛型<K>
public object TextFunc<K>(K temp_i)
Console.WriteLine("TextFunc<K>");
return temp_i.GetType();
回到主入口Main这边来
using System;
using System.Reflection;//反射必备的命名空间
namespace Util
internal class Program{
private static void Main(string[] args)
//通过Assembly的API:LoadFrom获取到程序集对象
Assembly utilAss = Assembly.LoadFrom(@"F:\C#学习\C# item\Util\bin\Debug\Util.dll");
//通过Assembly的API:GetType获取UtilPackage的类型Type 注意:这里的名称是Util.UtilPackage`1
Type utilPackageType = utilAss.GetType("Util.UtilPackage`1");
//将其泛型初始类具体的实例为已实例过的泛型类
Type utilPackageType_Generic_int = utilPackageType.MakeGenericType(new Type[]{typeof(int)});
//对于泛型类还需要用到Type的API:MakeGenericType去实例出泛型类
//将其实例成具体的对象
object utilPackageObj = Activator.CreateInstance(utilPackageType_Generic_int);
//-------------------------------------------------------分割符
//通过Type的API:GetProperty获取属性
PropertyInfo utilPackage_ValueProperty = utilPackageType_Generic_int.GetProperty("Value");
//同理取得UtilGenericType
PropertyInfo utilPackage_TypeProperty = utilPackageType_Generic_int.GetProperty("UtilGenericType");
string temp_m = utilPackage_ValueProperty.GetValue(utilPackageObj).ToString();
string temp_n = utilPackage_TypeProperty.GetValue(utilPackageObj).ToString();
Console.WriteLine("Value:"+temp_m+"|GenericType:"+temp_n);
Console.WriteLine("//-------------------------------------------------------分割符" );
//-------------------------------------------------------分割符
//先获取方法
MethodInfo func = utilPackageType_Generic_int.GetMethod("TextFunc");
//再将方法转为泛型方法
func = func.MakeGenericMethod(new Type[] { typeof(int) });
//调用TextFunc并将返回值输出
Console.WriteLine(func.Invoke(utilPackageObj, new object[] { 1}));
当读者执行完代码时,输出结果为:
Value:0|GenericType:System.Int32
TextFunc<K>
System.Int32
第五阶段:通过反射获取泛型(独立)
#region 实体逻辑特性类
/// <summary>
/// 特性:实体逻辑类 用于标注这是一个逻辑函数
/// </summary>
[AttributeUsage( AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public sealed class LogicAttribute : Attribute
#region Field
/*字段注释
*name:逻辑名称
*note:逻辑注释
*index:逻辑序号
private string name;
private string note;
private int index;
#endregion
#region Property
/// <summary>
/// 逻辑的名称
/// </summary>
public string Name => name;
/// <summary>
/// 逻辑的注释
/// </summary>
public string Note => note;
/// <summary>
/// 逻辑的序号
/// </summary>
public int Index => index;
#endregion
#region Constructor
/// <summary>
/// 构造函数:初始化逻辑特性
/// </summary>
public LogicAttribute(string _Name,string _Note,int _Index)
this.name = _Name;
this.note = _Note;
this.index = _Index;
#endregion
#endregion
#region 实体逻辑模块
public abstract class Logic
#region Field
/*字段注释
* Name :逻辑名称
* index:逻辑状态标识
* logic:逻辑函数主体 状态标识:(逻辑名称,逻辑特性,逻辑函数)
protected string name;
protected int state;
protected Dictionary<int,Tuple<string,LogicAttribute,MethodInfo>> logic;
#endregion
#region Property
/// <summary>
/// 逻辑名称
/// </summary>
public string Name => this.name;
/// <summary>
/// 逻辑状态标识
/// </summary>
public int State => this.state;
#endregion
#region Constructor
/// <summary>
/// 构造函数:初始化逻辑的名称以及状态还有逻辑的函数
/// </summary>
/// <param name="_Name">逻辑总体名称</param>
/// <param name="_State">逻辑状态,默认为1</param>
protected Logic(string _Name,int _State = 1)
this.name = _Name;
this.state = _State;
//将其实例化
logic = new Dictionary<int, Tuple<string, LogicAttribute, MethodInfo>>();
//获取自身类型对象
Type type = this.GetType();
//查找自身函数标注了LogicAttribute特性的函数
MethodInfo[] methods =
type.GetMethods().Where(p => p.IsDefined(typeof(LogicAttribute))).ToArray();
for (int i = 0; i < methods.Length;i++)
//获取逻辑函数上标注的特性
LogicAttribute logicattribute =
methods[i].GetCustomAttribute(typeof(LogicAttribute),true)
as LogicAttribute;
//创建一个元组,用于存放
Tuple<string,LogicAttribute, MethodInfo> temp_Tuple = new Tuple<string, LogicAttribute, MethodInfo>(logicattribute.Name,logicattribute, methods[i]);
//Console.WriteLine(temp_Tuple);
//将其添加进逻辑函数字典中
logic.Add(logicattribute.Index,temp_Tuple);
#endregion
#region Method
/// <summary>
/// 函数:执行
/// </summary>
public abstract void Invoke();
/// <summary>
/// 函数:移除
/// </summary>
public abstract void Remove();
#endregion
public class TestLogic : Logic
public TestLogic(string _Name, int _State = 1) : base(_Name, _State)
Console.WriteLine("测试用的逻辑");
public override void Invoke()
foreach (var temp in logic)
Console.WriteLine(temp);
public override void Remove()
Console.WriteLine("执行了Remove函数");
[Logic("测试函数","专门用来测试的函数",1)]
public void func()
Console.WriteLine("执行了测试函数");
[Logic("测试函数1", "专门用来测试的函数", 2)]
public void func1()
Console.WriteLine("执行了测试函数");
[Logic("测试函数2", "专门用来测试的函数", 3)]
public void func2()
Console.WriteLine("执行了测试函数");
[Logic("测试函数3", "专门用来测试的函数", 4)]
public void func3()
Console.WriteLine("执行了测试函数");
private static void Main(string[] args)
Logic logic = new TestLogic("测试用");
logic.Invoke();
测试用的逻辑
[1, (测试函数, Entity.LogicAttribute, Void func())]
[2, (测试函数1, Entity.LogicAttribute, Void func1())]
[3, (测试函数2, Entity.LogicAttribute, Void func2())]
[4, (测试函数3, Entity.LogicAttribute, Void func3())]
org.apache.util.ReflactionUtil
1.内部类CopyInCopyOutBuffer(线程池管理) 结合类SerializationFactory(单例模式管理) 序列化和反序列化copy
private static class CopyInCopyOutBuffer {
DataOutputBuffer outBuffer = new DataOutp
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
public class
Reflection
Utils
近段时间,有朋友叫Insus
.NET
了解一下
反射
(
Reflection
)方面的知识,
反射
提供了封装程序集、模块和类型的对象(Type类型)。可以使用
反射
动态创建类型的实例,将类型绑定到现有对象,或从现有对象获取类型并调用其方法或访问其字段和属性。如果代码中使用了属性,可以利用
反射
对它们进行访问。下面的例子,是Insus
.NET
是练习对一个类别的属性进行set和get值。
首先写一个类,再写一个可...
public string Apple {get;set;}
public string Banana{get;set;}
public string Orange {get;set;}
public string Pineapple {get;set;}
public stri...
反射
指程序可以访问、检测和修改它本身状态或行为的一种能力。
程序集包含模块,而模块包含类型,类型又包含成员。
反射
则提供了封装程序集、模块和类型的对象。
您可以使用
反射
动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。然后,可以调用类型的方法或访问其字段和属性。
1、
反射
提高了程序的灵活性和扩展性。
2、降低耦合性,提高自适应能力。
3、它允许
反射
指程序可以访问、检测和修改它本身状态或行为的一种能力,可以使用
反射
动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。然后,可以调用类型的方法或访问其字段和属性。
反射
用途:
它允许在运行时查看特性信息。
它允许审查集合中的各种类型,以及实例化这些类型。
它允许延迟绑定的方法和属性。
它允许在运行时创建新类型,然后使用这些类型执行一些任务。
反射
的优点:
1、
反射
提...
CSDN-Ada助手: