.net基础—反射
反射
反射提供描述程序集、模块和类型的对象(Type 类型)。 可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型,然后调用其方法或访问器字段和属性。 如果代码中使用了特性,可以利用反射来访问它们。
反射的类位于System.Reflection命名空间中,他们是.net Reflection API的一部分,所以在使用的反射的程序中一般都要使用 System.Reflection的命名空间。
System. Type类包装了类型,因此是整个反射子系统的核心,这个类中包含了很多属性和方法,使用这些属性和方法可以在运行时得到类型的信息。
通过反射获取类型信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | internal class Program { static void Main( string [] args) { //获取类型信息 Type t = typeof ( int ); Console.WriteLine($ "命名空间名称:{t.Namespace}" ); Console.WriteLine($ "基类:{t.BaseType}" ); Console.WriteLine($ "全名:{t.FullName}" ); Console.WriteLine($ "是否为抽象类型:{t.IsAbstract}" ); Console.WriteLine($ "是否为密封类:{t.IsSealed}" ); //获取所以公有成员 Type t2 = typeof (TestClass); var mi = t2.GetMembers(); //获取所以公有成员 foreach ( var m in mi) { //Console.WriteLine($"【{m.MemberType.ToString()} : {m.Name}】"); } //获取方法相关的信息 MethodInfo[] methodList = t.GetMethods(); foreach ( var m in methodList) { Console.Write($ "方法的返回类型:{m.ReturnType.Name}" ); Console.Write($ "方法的名称:{m.Name} (" ); //获取方法参数列表并保持在ParameterInfo对象数组中 ParameterInfo[] parameters = m.GetParameters(); for ( int i = 0; i < parameters.Length; i++) { Console.Write($ "方法的参数类型名称{parameters[i].ParameterType.Name}" ); Console.Write($ "方法的参数名{parameters[i].Name}" ); if (i + 1 < parameters.Length) { Console.Write($ ", " ); } } Console.Write($ ")" ); Console.WriteLine(); } Console.ReadLine(); } } class TestClass { public string TestName { get ; set ; } public int Sum( int x, int y) { return x + y; } } |
通过反射调用构造函数和方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | internal class Program { static void Main( string [] args) { #region 使用反射调用程序集中类型中的方法 //加载dll Assembly assembly = Assembly.Load( "DemoLibrary" ); //获取类型信息 Type type = assembly.GetType( "DemoLibrary.DemoClass" ); object demoClass = Activator.CreateInstance(type); //创建对象 DemoClass demo = (DemoClass)demoClass; //类型转换 demo.Show(); //方法调用 #endregion #region 调用不同参数的构造函数 Type type2 = assembly.GetType( "DemoLibrary.DemoClass2" ); object demoClass2 = Activator.CreateInstance(type2); object demoClass22 = Activator.CreateInstance(type2, new object [] { 123}); object demoClass222 = Activator.CreateInstance(type2, new object [] { "abc" }); #endregion #region 调用泛型 // `占位符;2表示参数个数(一个的时候也要写) Type type3 = assembly.GetType( "DemoLibrary.Demo3`2" ); //object demo3 = Activator.CreateInstance(type3); //这么写报错,因为没有指定类型 //指定泛型的参数类型 Type newType = type3.MakeGenericType( new Type[] { typeof ( int ), typeof ( string ) }); object objNewType = Activator.CreateInstance(newType); #endregion Console.ReadKey(); } } |
程序集中的类:
DemoClass:
1 2 3 4 5 6 7 8 9 10 11 12 | public class DemoClass { public DemoClass() { Console.WriteLine($ "{this.GetType().Name} 被构造" ); } public void Show() { Console.WriteLine($ "{this.GetType().Name}.Show" ); } } |
DemoClass2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | public class DemoClass2 { /// <summary> /// 无参数构造函数 /// </summary> public DemoClass2() { Console.WriteLine($ "这是无参数{this.GetType().Name} 构造函数" ); } /// <summary> /// 带参数的构造函数 /// </summary> public DemoClass2( string strVal) { Console.WriteLine($ "这有参数{this.GetType().Name} 构造函数,传入的值:{strVal}" ); } /// <summary> /// 带参数的构造函数 /// </summary> public DemoClass2( int intVal) { Console.WriteLine($ "这有参数{this.GetType().Name} 构造函数,传入的值:{intVal}" ); } } |
Demo3:
1 2 3 4 5 6 7 | public class Demo3<T, X> { public void Show(T t, X x) { Console.WriteLine($ "t.type={t.GetType()},x.type={x.GetType()}" ); } } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?