C#泛型和反射实例解析
2023-06-13 09:15:41 时间
C#中的泛型和反射经常是一起工作的,因此这里就一次性的加以介绍了。
由于c#是强类型语言,一般来说函数的返回类型和参数的类型都是一早写好的,这也就造成了很多时候不像js那样方便使用,不够灵话。
因此就有了这个泛型,它可以让你的函数和参数在调用的时候才决定类型。如下例所示:
publicTabc<T>(Tword) { returnword; returndefault(T);//关键字default可以对引用类型返回nullAble,int类型返回0,初始化一个T的感觉啦 } abc<string>("x"); //struct是值类型 //好处调用的是如果参数是值类型可以不用著名test(100)而不需要test<int>(100); publicvoidtest<T>(Tnumber)whereT:struct { intz=Convert.ToInt32(number); //调用test(100); } //下面的不知道好处在哪用在什么地方, publicvoidtest2<T>(Tlei)whereT:class { } publicvoidtest3<T>()whereT:stooges { } publicTtest4<T>()whereT:new() { Tabc=newT(); returnabc; } publicclassstooges { }
加了where我就不清楚在什么地方用的上了,这个以后再研究
先来一个常用到的,我们想获取一个对象的全部属性和值,用js是:
for(varattrinobject){object[attr]=value,attr=attr} varobj=newabc(); TypeT=typeof(abc);//typeof(Class)而不是typeof(object)哦 TypeV=obj.GetType();//obj.GetType()就是typeof(object的class) PropertyInfo[]attrs=obj.GetType().GetProperties(BindingFlags.Instance|BindingFlags.Public);//获取attrs foreach(PropertyInfoattrinattrs) { stringkey=attr.Name;//获取attrname objectvalue=attr.GetValue(obj,null);//获取value Typetype=attr.PropertyType;//类型 }
关键就是那个Type,获取Type后就可以做很多了
C#常用的方法为:
T.GetProperty("key").GetValue(obj,null);//readakeyvalue T.GetProperty("key").SetValue(obj,"",null);//writeavaluetokey //注意如果是字典 T.GetProperty("Item").GetValue(obj,new[]{"id"});//先拿Item然后才通过new[]{这里放指定的key}
再来看看更详细的
classMyClass { publicintx{get;set;} publicinty{get;set;} publicMyClass(inti) { x=y+i; } publicMyClass(inti,intj) { x=i; y=j; } publicintsum() { returnx+y; } }
我们想获取这个Class的构造函数:
Typet=typeof(MyClass); ConstructorInfo[]constructors=t.GetConstructors();//使用这个方法获取构造函数列表 for(inti=0;i<constructors.Length;i++) { ConstructorInfoconstructor=constructors[i]; //构造函数也是方法所以有GetParameters ParameterInfo[]parameters=constructor.GetParameters();//获取当前构造函数的参数列表 stringparaTypeName=parameters[0].ParameterType.Name;//方法的参数类型名称 stringparaName=parameters[0].Name;//方法的参数名 } //调用构造函数 object[]args=newobject[2]; args[0]=10; args[1]=20; //不用new直接实例化 objectinstance=constructors[0].Invoke(args);//实例化一个这个构造函数有两个参数的类型对象,如果参数为空,则为null objectinstance=(t)Activator.CreateInstance(t);还有这种实例的方法,不清楚可以放参数没有
调用方法如下:
MethodInfo[]methods=T.GetMethods(BindingFlags.Public|BindingFlags.DeclaredOnly|BindingFlags.Instance); foreach(MethodInfomethodinmethods) { stringreturn_name=method.ReturnType.Name;//返回方法的返回类型 stringname=method.Name; if(name.Equals("sum",StringComparison.Ordinal))//指定方法名调用 { intvalue=(int)method.Invoke(instance,null);//instance是之前实例好的对象,方法就是在这个对象之中 } }
下面是一些参考代码:
Typet=typeof(MyClass); Console.WriteLine("----------------Method------------------"); MethodInfo[]methods=t.GetMethods(); foreach(MethodInfomethodinmethods) { Console.WriteLine("Method:"+method); //Console.WriteLine(method); //Console.WriteLine("返回值:"+method.ReturnParameter); } Console.WriteLine("---------------Field-------------------");//字段,比如这种privatestaticstringname; FieldInfo[]fields=t.GetFields(BindingFlags.NonPublic|BindingFlags.Instance|BindingFlags.Static); foreach(FieldInfofieldinfields) { Console.WriteLine("Field:"+field); } Console.WriteLine("--------------Member--------------------");//成员即方法和属性 MemberInfo[]members=t.GetMembers(); foreach(MemberInfomemberinmembers) { Console.WriteLine("Member:"+member); } Console.WriteLine("--------------Property--------------------");//属性 PropertyInfo[]properties=t.GetProperties(); foreach(PropertyInfopropertyinproperties) { Console.WriteLine("Property:"+property); } Console.WriteLine("--------------Constructor--------------------");//构造函数 ConstructorInfo[]constructors=t.GetConstructors(BindingFlags.NonPublic|BindingFlags.Instance); foreach(ConstructorInfoconstructorinconstructors) { Console.WriteLine("Constructor:"+constructor); }
调用不用记太清楚,关键知道什么东西可以用反射获取和调用就可以了。
还有通过string来调用方法,这个在js很长用到,比如obj["methodName"]();这里也可以用到反射来实现。
此外还需要注意:反射的性能是很慢的,也可以说动态就是慢,这个是很正常的,反射的性能优化可以参考使用动态编程之类的,不过这里就不提了。
相关文章
- c# Response.ContentType类型汇总
- C#TextBox密码框
- 【Unity3D】Unity 中使用 C# 调用 Java ③ ( C# 调用 Java 实例 | 进行 Android 工程打包 | Android Studio 中运行 Android 工程 )
- C#/.NET程序运行流程
- C#装箱和拆箱
- C#索引器简单实例代码
- C#Dictionary的使用实例代码
- 关于C#5.0CallerMemberNameCallerFilePathCallerLineNumber在.NET4中的使用介绍方法
- C#泛型与非泛型性能比较的实例
- C#DES加密算法中向量的作用详细解析
- C#由当前日期计算相应的周一和周日的实例代码
- c#dataTable合并两个列到一个新列中的简单实例
- c#DataTable与不同结构实体类转换的方法实例
- C#加密解密类实例程序
- C#引用类型和值类型的介绍与实例
- C#基本概念列举详解
- C#函数式程序设计之用闭包封装数据的实现代码
- C#中if语句使用概述
- 使用C#在注册表中保存信息的例子
- C#实现的SN快速输入工具实例
- C#生成随机数实例
- C#缓存之SqlCacheDependency用法实例总结
- C#中this的使用实例分析
- C#托管堆对象实例包含内容分析