C#泛型和反射实例解析

C#中的泛型和反射经常是一起工作的,因此这里就一次性的加以介绍了。

由于c#是强类型语言,一般来说函数的返回类型和参数的类型都是一早写好的,这也就造成了很多时候不像js那样方便使用,不够灵话。

因此就有了这个泛型,它可以让你的函数和参数在调用的时候才决定类型。如下例所示:

public T abc<T>(T word)
{
return word;
return default(T); //关键字default可以对引用类型返回nullAble,int类型返回0,初始化一个T的感觉啦
}

abc<string>("x");

//struct 是 值类型
//好处调用的是如果参数是值类型可以不用著名 test(100) 而不需要 test<int>(100);
public void test<T>(T number) where T : struct
{
int z = Convert.ToInt32(number);
//调用 test(100);
}
//下面的不知道好处在哪用在什么地方,
public void test2<T>(T lei) where T : class
{
}
public void test3<T>() where T : stooges
{
}
public T test4<T>() where T : new()
{
T abc = new T();
return abc;
}
public class stooges
{
}

加了where 我就不清楚在什么地方用的上了,这个以后再研究

反射能让我们的代码运行时动态的获取一些对象或者类的属性值等等,甚至是调用它们。

先来一个常用到的,我们想获取一个对象的全部属性和值, 用js 是:

for(var attr in object) { object[attr]=value, attr = attr }
var obj = new abc();
Type T = typeof(abc); //typeof(Class) 而不是 typeof(object) 哦
Type V = obj.GetType(); //obj.GetType() 就是typeof(object的class)
PropertyInfo[] attrs = obj.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public); //获取attrs
foreach (PropertyInfo attr in attrs)
{
string key = attr.Name; //获取attr name
object value = attr.GetValue(obj, null); //获取value
Type type = attr.PropertyType; //类型
}

关键就是那个 Type , 获取Type后就可以做很多了

C#常用的方法为:

T.GetProperty("key").GetValue(obj, null); //read a key value
T.GetProperty("key").SetValue(obj, "", null); //write a value to key
//注意如果是字典
T.GetProperty("Item").GetValue(obj, new [] {"id"}); //先拿Item 然后才通过 new[] {这里放指定的key}

再来看看更详细的

class MyClass
{
public int x { get; set; }
public int y { get; set; }
public MyClass(int i)
{
  x = y + i;
}
public MyClass(int i, int j)
{
  x = i;
  y = j;
}
public int sum()
{
  return x + y;
}
}

我们想获取这个Class 的构造函数 :

Type t = typeof(MyClass);
ConstructorInfo[] constructors = t.GetConstructors(); //使用这个方法获取构造函数列表
for (int i = 0; i < constructors.Length; i++)
{
ConstructorInfo constructor = constructors[i];
//构造函数也是方法所以有 GetParameters
ParameterInfo[] parameters = constructor.GetParameters(); //获取当前构造函数的参数列表
string paraTypeName = parameters[0].ParameterType.Name; //方法的参数类型名称
string paraName = parameters[0].Name;// 方法的参数名
}
//调用构造函数
object[] args = new object[2];
args[0] = 10;
args[1] = 20;
//不用new 直接实例化
object instance = constructors[0].Invoke(args); //实例化一个这个构造函数有两个参数的类型对象,如果参数为空,则为null
object instance = (t)Activator.CreateInstance(t); 还有这种实例的方法,不清楚可以放参数没有

调用方法如下:

MethodInfo[] methods = T.GetMethods(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance);
foreach (MethodInfo method in methods)
{
string return_name = method.ReturnType.Name; //返回方法的返回类型
string name = method.Name;
if (name.Equals("sum", StringComparison.Ordinal)) //指定方法名调用
{
  int value = (int)method.Invoke(instance, null); //instance是之前实例好的对象,方法就是在这个对象之中
}
}

下面是一些参考代码:

Type t = typeof(MyClass);
Console.WriteLine("----------------Method------------------");
MethodInfo[] methods = t.GetMethods();
foreach (MethodInfo method in methods)
{
  Console.WriteLine("Method:" + method);
  //Console.WriteLine(method);
  //Console.WriteLine("返回值:" + method.ReturnParameter);
}
Console.WriteLine("---------------Field-------------------"); //字段 ,比如这种 private static string name;
FieldInfo[] fields = t.GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
foreach (FieldInfo field in fields)
{
  Console.WriteLine("Field:" + field);
}
Console.WriteLine("--------------Member--------------------"); //成员即方法和属性
MemberInfo[] members = t.GetMembers();
foreach (MemberInfo member in members)
{
  Console.WriteLine("Member:" + member);
}
Console.WriteLine("--------------Property--------------------"); //属性
PropertyInfo[] properties = t.GetProperties();
foreach (PropertyInfo property in properties)
{
  Console.WriteLine("Property:" + property);
}
Console.WriteLine("--------------Constructor--------------------"); //构造函数
ConstructorInfo[] constructors = t.GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance);
foreach (ConstructorInfo constructor in constructors)
{
  Console.WriteLine("Constructor:" + constructor);
}

调用不用记太清楚,关键知道什么东西可以用反射获取和调用就可以了。

比较常使用的地方是用泛型写方法的时候,比如我们的泛型是一个不确定的类,然后我们要获取attr值等等的,就很好可以使用反射了。

还有通过string来调用方法,这个在js很长用到,比如 obj["methodName"](); 这里也可以用到反射来实现。

此外还需要注意: 反射的性能是很慢的,也可以说动态就是慢,这个是很正常的,反射的性能优化可以参考使用动态编程之类的,不过这里就不提了。

(0)

相关推荐

  • c#反射调用方法示例

    获取方法的相关信息的两种形式 反射是一种允许用户获得类信息的C#功能,Type对象映射它代表的底层对象: 在.Net 中, 一旦获得了Type对象,就可以使用GetMethods()方法获取此类型支持的方法列表:该方法的两种形式: MethodInfo [] GetMethods() MethodInfo [] GetMethods(BindingFlags bindingflas)  :它的参数带有一些限制 BindingFlags  是一个枚举 枚举成员 [DeclaredOnly,Inst

  • C#属性(Attribute)用法实例解析

    属性(Attribute)是C#程序设计中非常重要的一个技术,应用范围广泛,用法灵活多变.本文就以实例形式分析了C#中属性的应用.具体入戏: 一.运用范围 程序集,模块,类型(类,结构,枚举,接口,委托),字段,方法(含构造),方法,参数,方法返回值,属性(property),Attribute [AttributeUsage(AttributeTargets.All)] public class TestAttribute : Attribute { } [TestAttribute]//结构

  • 关于C#基础知识回顾--反射(一)

    反射(reflection)是一种允许用户获得类型信息的C#特性.术语"反射"源自于它的工作方式:Type对象映射它所代表的底层对象.对Type对象进行查询可以获得(反射)与类型相关的信息.反射是一种功能强大的机制,它允许学习和使用只在运行时才能知道的类型功能. 这些是官方定义,其实说白了,反射就是能知道我们未知类型的类型信息这么一个东西.没什么神秘可讲!反射的核心是System.Type.System.Type包含了很多属性和方法,使用这些属性和方法可以在运行时得到类型信息.一旦得到

  • C#基础学习系列之Attribute和反射详解

    前言 本文主要给大家介绍了关于C#基础之Attribute和反射的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. Attribute(特性) Attribute是C#的一种语言特性,用于为各种实体(class,field,property)附加一些说明性信息, 并且可以在运行时环境中检索这些信息(通过反射). 所有的Attribute必须继承自Attribute类,按照约定,特性类的名称带有 Attribute 后缀.使用特性时可以包含或省略此后缀. Attribut

  • C#中的程序集和反射介绍

    什么是程序集? 1.程序集(assembly)是一个及一个以上托管模块,以及一些资源文件的逻辑组合. 2.程序集是组件复用,以及实施安全策略和版本策略的最小单位. 3.程序集是包含一个或者多个类型定义文件和资源文件的集合.在程序集包含的所有文件中,有一个文件用于保存清单.(清单是元数据部分中一组数据表的集合,其中包含了程序集中一部分文件的名称,描述了程序集的版本,语言文化,发布者,共有导出类型,以及组成该程序集的所有文件). 4.在编译应用程序中,所创建的CIL代码存储在一个程序集中,程序集包括

  • C#中Property和Attribute的区别实例详解

    本文实例分析了C#中Property和Attribute的区别.分享给大家供大家参考.具体分析如下: 在C#中有两个属性,分别为Property和Attribute,两个的中文意思都有特性.属性之间,但是用法上却不一样,为了区别,本文暂把Property称为特性,把Attribute称为属性. Attribute才是本文的主角,把它称为属性我觉得很恰当.属性的意思就是附属于某种事物上的,用来说明这个事物的各种特征的一种描述.而Attribute就是干这事的.它允许你将信息与你定义的C#类型相关联

  • C#反射的一些应用

    对于反射贫道也是很陌生的,所以趁现在有时间就把反射看了一下,记下笔记!!!反射的定义:反射(Reflection)是.NET中的重要机制,通过放射,可以在运行时获得.NET中每一个类型(包括类.结构.委托.接口和枚举等)的成员,包括方法.属性.事件,以及构造函数等.还可以获得每个成员的名称.限定符和参数等.有了反射,即可对每一个类型了如指掌.如果获得了构造函数的信息,即可直接创建对象,即使这个对象的类型在编译时还不知道.  1,导入using System.Reflection;  2,Asse

  • C#反射实例学习及注意内容

    C#反射的入门学习首先要明白C#反射提供了封装程序集.模块和类型的对象等等.那么这样可以使用反射动态创建类型的实例,将类型绑定到现有对象,或从现有对象获取类型并调用其方法或访问其字段和属性.如果代码中使用了属性,可以利用反射对它们进行访问. MSDN描述: 反射通常具有以下用途: 使用 Assembly 定义和加载程序集,加载在程序集清单中列出的模块,以及从此程序集中查找类型并创建该类型的实例. 使用 Module 发现以下信息:包含模块的程序集以及模块中的类等.您还可以获取在模块上定义的所有全

  • C#泛型和反射实例解析

    C#中的泛型和反射经常是一起工作的,因此这里就一次性的加以介绍了. 由于c#是强类型语言,一般来说函数的返回类型和参数的类型都是一早写好的,这也就造成了很多时候不像js那样方便使用,不够灵话. 因此就有了这个泛型,它可以让你的函数和参数在调用的时候才决定类型.如下例所示: public T abc<T>(T word) { return word; return default(T); //关键字default可以对引用类型返回nullAble,int类型返回0,初始化一个T的感觉啦 } ab

  • java泛型常用通配符实例解析

    这篇文章主要介绍了java泛型常用通配符实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 今天在看ArrayList原码是看到这样的一个符号,好奇怪. ?表示通配符,表示的意思是匹配E或E的子类,具体类型未知. 1.限定通配符 编写一个类似于ArrayList的动态数据 public class Gys<T> { private final static int default_capacity =10; private int end

  • Java静态泛型使用方法实例解析

    前言:当工具类对多个模型类进行排序,比较等操作的时候,需要书写大量重复代码,因为懒人总要想怎么省事的,所以考虑使用泛型这个玩意简化代码 案例:当前存在两个模型类,Fruit和Person,他们都需要排序方法而且业务逻辑各不相同,因此需要分别写两个排序方法,但因为排序相同的地方太多,唯一的区别就是判断两个对象的大小关系,于是在此做简化操作. 执行步骤: 1.编写模型类接口 interface Model public interface Model<T> { public int compare

  • Java编程探索之泛型擦除实例解析

    1.问题引出 源码: public static void main(String[] args) { List<Integer> a = new ArrayList<Integer>(); List<String> b = new ArrayList<String>(); System.out.println(a.getClass() == b.getClass());//结果true } 编译后L public static void main(Stri

  • Java 中利用泛型和反射机制抽象DAO的实例

    Java 中利用泛型和反射机制抽象DAO的实例 一般的DAO都有CRUD操作,在每个实体DAO接口中重复定义这些方法,不如提供一个通用的DAO接口,具体的实体DAO可以扩展这个通用DAO以提供特殊的操作,从而将DAO抽象到另一层次,令代码质量有很好的提升 1.通用接口 import java.io.Serializable; import java.util.List; public interface BaseDao<T> { T get(Serializable id); List<

  • JavaScript 反射和属性赋值实例解析

    这篇文章主要介绍了JavaScript 反射和属性赋值实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 Java和.NET都有着比较完善的反射机制,用来处理未知的对象并获取它们的属性和方法.JavaScript虽然没有完善的反射体系,但在编程的时候还是可以通过代码设计来实现类似反射的基本功能. function Antzone(){ this.webName="蚂蚁部落"; this.age=6; } Antzone.proto

  • Python类反射机制使用实例解析

    这篇文章主要介绍了Python类反射机制使用实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 反射就是通过字符串的形式,导入模块:通过字符串的形式,去模块寻找指定函数并执行. Python有四个内置函数: 函数 功能 getattr(object, attr[, default]) 获取指定字符串名称的对象属性或方法,如果对象有该属性则返回属性值,如果有该方法则返回该方法的内存地址,如果都没有就报错,如果指定了默认值找不到不会报错会取默认

  • Java反射技术详解及实例解析

    前言 相信很多人都知道反射可以说是Java中最强大的技术了,它可以做的事情太多太多,很多优秀的开源框架都是通过反射完成的,比如最初的很多注解框架,后来因为java反射影响性能,所以被运行时注解APT替代了,java反射有个开源框架jOOR相信很多人都用过,不过我们还是要学习反射的基础语法,这样才能自己写出优秀的框架,当然这里所讲的反射技术,是学习Android插件化技术.Hook技术等必不可少的! 一.基本反射技术   1.1 根据一个字符串得到一个类 getClass方法 String nam

  • Golang泛型与反射的应用详解

    目录 1. 泛型 1.1 定义 1.2 例子 1.3 自定义泛型类型 1.4 泛型与switch结合使用 1.5 泛型实战 2. 反射 2.1 定义 2.2 方法 2.3 反射读取 2.4 反射操作 2.5 判断 1. 泛型 1.1 定义 泛型生命周期只在编译期,旨在为程序员生成代码,减少重复代码的编写 在比较两个数的大小时,没有泛型的时候,仅仅只是传入类型不一样,我们就要再写一份一模一样的函数,如果有了泛型就可以减少这类代码 1.2 例子 // SumInts 将map的值相加,如果需要添加的

  • 应用Java泛型和反射导出CSV文件的方法

    本文实例讲述了应用Java泛型和反射导出CSV文件的方法.分享给大家供大家参考.具体如下: 项目中有需求要把数据导出为CSV文件,因为不同的类有不同的属性,为了代码简单,应用Java的泛型和反射,写了一个函数,完成导出功能. 复制代码 代码如下: public <T> void saveFile(List<T> list, String outFile) throws IOException {         if (list == null || list.isEmpty())

随机推荐