时间:2023/12/19来源:本站原创作者:佚名
白癜风初期治疗费用 https://mjbk.familydoctor.com.cn/bjbdfyy_zx/

上篇文章讲述了C#异常处理知识点,本文将介绍C#反射的知识点。反射(Reflection)是C#中一个强大而复杂的特性,它允许开发人员在运行时获取和操作程序集、类型和对象的信息。本文将介绍C#反射的一些知识点,希望对大家开发有一定的帮助。

1、什么是反射?首先了解一下概念,官方介绍“System.Reflection命名空间中的类与System.Type使你能够获取有关加载的程序集和其中定义的类型的信息,如类、接口和值类型(即结构和枚举)。可以使用反射在运行时创建、调用和访问类型实例“。通俗的讲反射是C#中的一项技术,允许开发人员在运行时访问和操作程序集、类型和对象的信息。通过反射,您可以动态加载程序集、创建对象实例、调用方法、访问属性和字段,甚至在不知道类型的情况下操作对象。

详解--基础:C#反射(Reflection)详解

2、使用反射获取类型信息使用反射可以获取有关类型的各种信息,例如名称、命名空间、基类、属性、方法和字段。获取类的信息可以做扩展开发,比如ORM的EF框架里就用了大量的反射来获取类的信息(早前版本)。以下是一些常用的反射方法:

Typetype=typeof(TestClass);//获取类型stringtypeName=type.FullName;//获取类型的完整名称TypebaseType=type.BaseType;//获取基类类型PropertyInfo[]properties=type.GetProperties();//获取属性信息MethodInfo[]methods=type.GetMethods();//获取方法信息FieldInfo[]fields=type.GetFields();//获取字段信息Console.WriteLine("获取类型的完整名称:{typeName}");Console.WriteLine("获取基类类型:{baseType.Name}");Console.WriteLine("获取第一个属性信息:"+properties.FirstOrDefault());Console.WriteLine("获取第一个方法信息:"+methods.FirstOrDefault());Console.WriteLine("获取第一个字段信息:"+fields.FirstOrDefault());//下面是这个类publicclassTestClass{publicstaticstringTestName;publicstringName{get;set;}publicstringDescription{get;set;}publicstringGet(){return"DOTNET开发跳槽";}}

输出结果如下:

image.png

为啥第一个方法是get_Name()不是Get(),因为属性底层也是方法,只不过C#给简化了而已。

3、创建对象实例、调用方法和访问属性通过反射,您可以在代码运行时创建对象的实例。这对于在不知道类型的情况下实例化对象非常有用。

//TestClass案例跟第一个的类相同Typetype=typeof(TestClass);objectinstance=Activator.CreateInstance(type);//调用无参数方法MethodInfomethodInfo1=types.GetMethod("Get");stringresult=methodInfo1.Invoke(instance,null).ToString();Console.WriteLine("方法打印结果:{result}");//调用有参数方法,大家自己研究一下//获取属性值PropertyInfoproperty=type.GetProperty("Name");objectvalue=property.GetValue(instance);//由于未赋值,结果是null,这里就不打印了。

效果如下:

image.png

4、获取当前程序集信息

反射还允许您获取程序集的信息,包括版本号、公共密钥令牌和引用的其他程序集。通过获取程序集,你可以分析当前程序的调用情况等信息。

Assemblyassembly=Assembly.GetExecutingAssembly();//获取当前程序集stringassemblyName=assembly.GetName().Name;//获取程序集名称Versionversion=assembly.GetName().Version;//获取程序集版本byte[]publicKeyToken=assembly.GetName().GetPublicKeyToken();//获取公共密钥令牌varreferencedAssemblies=assembly.GetReferencedAssemblies();//获取引用的程序集列表//大家可以自行打印出来,比如上面的程序集assemblyName输出为Test8

5、使用反射处理自定义特性反射允许您检查和处理在代码中定义的自定义特性。特性是元数据,它可以用于为类型、方法、属性等添加元信息。

//Main里的调用类和自定义特性在下面Typetype=typeof(TestClass);MyCustomAttributeattribute=(MyCustomAttribute)Attribute.GetCustomAttribute(type,typeof(MyCustomAttribute));if(attribute!=null){//处理特性信息,这里打印特性Console.WriteLine("特性的值:"+attribute.Description);}//自定义特性sealedclassMyCustomAttribute:Attribute{publicstringDescription{get;}publicMyCustomAttribute(stringdescription){Description=description;}}//使用特性[MyCustomAttribute("输入名字!!")]publicclassTestClass{publicstringName{get;set;}}

输出结果:

image.png

当然也可以获得方法的特性,需要通过反射后的GetMethods获取所有方法,然后遍历方法并通过上面的方式获取特性的值或者执行处理逻辑。

6、泛型反射泛型反射是一种用于操作泛型类型和方法的反射技术。通过泛型反射,您可以动态地创建和操作泛型类型的实例,调用泛型方法,以及检查泛型类型的参数。这是泛型的高级用法,使用频率不是很高。

//获取泛型类型List的类型信息TypegenericType=typeof(List);//定义泛型类型的类型参数(这里是int)Type[]typeArgs={typeof(int)};//使用MakeGenericType方法创建泛型类型的实例TypeconstructedType=genericType.MakeGenericType(typeArgs);//使用Activator.CreateInstance方法创建泛型类型的对象实例objectinstance=Activator.CreateInstance(constructedType);//向列表添加数据dynamiclist=instance;//使用dynamic类型来调用泛型列表的Add方法list.Add(2);list.Add(3);list.Add(7);//使用泛型列表进行数据处理intsum=0;foreach(intiteminlist){sum+=item;}Console.WriteLine("求和值:"+sum);//输出结果:12

7、程序集加载程序集加载是反射中的一个关键概念,它涉及将程序集加载到应用程序域中以供使用。您可以使用Assembly.Load系列方法来加载程序集,还可以实现自定义的程序集加载逻辑。通常来获得引用类库项目和引用的dll序集文件。

Assemblyassembly=Assembly.Load("MyAssembly");Typetype=assembly.GetType("MyNamespace.MyClass");//接下来就可以调用以上类的方法了,调用方法跟前面的调用方法一致

8、反射注意事项性能和安全问题:尽管反射功能非常强大,性能和安全也是它的诟病。反射操作通常比直接调用代码要慢,并且可能导致性能下降。此外,反射可以访问私有成员和执行敏感操作,因此必须谨慎使用,并且需要足够的权限。对于性能和安全要求高的项目尽量不使用反射。

避免滥用反射:反射是一把双刃剑。尽管它可以解决某些问题,但滥用反射可能导致代码的可读性下降,并增加调试和维护的难度。在编写代码时,应仔细考虑是否真的需要使用反射来解决问题,是否有更好的替代方案。比如.NET的AOT打包发布方式也不支持反射代码,因为反射是运行时编译。

了解性能优化技巧:如果您必须使用反射,可以采取一些性能优化措施,例如缓存类型信息以减少反射调用的开销,或使用委托来加速方法调用。

结语

本文讲述了C#反射的一些知识点,比如获取类型、获取程序集,这些知识点都是.NET开发应该掌握的。反射不仅可以帮助您实现某些动态和通用的编程任务,还可以加强您的调试和开发技能。

希望本文提供的C#反射知识对每个.NET开发者都有所帮助,对于C#反射的知识点,你还知道哪些?欢迎留言讨论或者吐槽本文。

参考:

1、微软
转载请注明原文网址:http://www.helimiaopu.com/cxtx/cxtx/12869.html

------分隔线----------------------------