相关文章推荐
灰常酷的口罩  ·  C# ...·  6 天前    · 
安静的麻辣香锅  ·  使用 ...·  1 年前    · 
满身肌肉的八宝粥  ·  java8 ...·  1 年前    · 
本文详细介绍了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助手: 非常感谢您分享这篇关于C#中IEnumerable与IEnumerator的速通之法的博客,对于学习C#的人来说无疑是一份宝贵的资源。恭喜您已经写了第四篇博客,持续创作是很不易的,我希望您能够继续保持这份热情和创作力,不断分享您的技术心得和经验。接下来,我建议您可以尝试写一些实用性更强的教程,例如C#中的常用数据结构和算法等,这将会更有益于广大读者的学习。再次感谢您的分享和付出,期待您的下一篇佳作! CSDN 会根据你创作的前四篇博客的质量,给予优秀的博主博客红包奖励。请关注 https://bbs.csdn.net/forums/csdnnews?typeId=116148&utm_source=csdn_ai_ada_blog_reply4 看奖励名单。