泛型和反射

泛型和反射经常是一起工作的,所以就一次介绍吧.

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后就可以做很多了

常用的方法

        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"](); 这里也可以用到反射来实现。

p.s : 反射的性能是很慢的,也可以说动态就是慢,这个很正常啦,反射的性能优化可以参考使用动态编程之类的,不过这里就不提先啦。

泛型和反射

时间: 2024-11-10 15:59:31

泛型和反射的相关文章

用泛型和反射实现函数通用

使用泛型和反射机制事项函数的通用,写下来,欢迎吐槽 代码示例使用vb. net Imports System.Reflection Module Module1 Sub Main() Dim lst1 As List(Of Person) = New List(Of Person)() Dim lst2 As List(Of Person) = New List(Of Person)() Dim lstT As List(Of Person) = New List(Of Person)() Fo

框架学习前基础加强 泛型,注解,反射(泛型&注解)应用案例,IOC,Servlet3.0,动态代理,类加载器

泛型 1. 泛型类 :具有一个或多个类型变量的类,称之为泛型类! class A<T> { } 2. 在创建泛型类实例时,需要为其类型变量赋值 A<String> a = new A<String>(); * 如果创建实例时,不给类型变量赋值,那么会有一个警告! 3. 泛型方法 :具有一个或多个类型变量的方法,称之为泛型方法! class A<T> { public T fun(T t1) {} } fun()方法不是泛型方法!它是泛型类中的一个方法! pu

Java高质量代码之 — 泛型与反射

在Java5后推出了泛型,使我们在编译期间操作集合或类时更加的安全,更方便代码的阅读,而让身为编译性语言的Java提供动态性的反射技术,更是在框架开发中大行其道,从而让Java活起来,下面看一下在使用泛型和反射需要注意和了解的事情? 1.Java的泛型是类型擦除的????? Java中的泛型是在编译期间有效的,在运行期间将会被删除,也就是所有泛型参数类型在编译后都会被清除掉.请看以下例子? Java代码??? publicstaticvoid?test(List??testParameter)?

应用Java泛型和反射导出CSV文件

项目中有需求要把数据导出为CSV文件,因为不同的类有不同的属性,为了代码简单,应用Java的泛型和反射,写了一个函数,完成导出功能. public <T> void saveFile(List<T> list, String outFile) throws IOException { if (list == null || list.isEmpty()) { return; } if (StringUtils.isEmpty(outFile)) { throw new Illega

实施 ORM 的两项要旨:泛型和反射

鄙人认为,实施 ORM 的两项要旨乃泛型和反射.下面开始看看怎么为 DAO 层添砖加瓦. 首先,在 DBAccess 基础上扩展 DBAccessORM 接口,形成基于 ORM 的数据调用. /** * 数据访问对象 * * @author Frank Cheung * */ public interface DBAccessORM extends DBAccess { /** * 查询单笔记录,返回实体 * * @param sql * 原生 SQL 语句 * @param clazz * P

java5核心基础泛型(2):泛型在反射中的应用

如何通过反射获取指定参数类型的构造函数? 贴代码如下: package highBasic.generic; /** * 泛型入门 */ import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; public class GenericTest { public static void main(St

(十一)泛型、反射和异常

JavaSE(十一) --泛型.反射和异常 一.泛型 泛型是javaSE1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数,这种参数类型可以用在类.接口和方法的创建中,分别称为泛型类.泛型接口.泛型方法. 在javaSE1.5之前,没有泛型的情况下,通过对类型Object的引用来实现参数的"任意化","任意化"带来的缺点是要做显示的强制类型转换,而用这种转换的要求是要求开发者对实际参数可以预知的情况下进行的.对于强制类型转换错误的情况,

java的泛型与反射机制

什么是泛型? 泛型,即"参数化类型".顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参). 为什么要使用泛型? 先看如下代码: public class GenericTest { public static void main(String[] args) { List list = new ArrayList(); list.add("qqyumidi"

泛型擦除 反射 自动装配

1.泛型擦除 package cn.itcast.demo; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; public class Demo1 { public static void main(String[] args) throws SecurityExceptio