C# 反射

3 篇文章 0 订阅

从元数据说起

元数据的定义是“描述数据的数据”(data about data)。以数据库为例,存储到数据库表中的数据是按照一定的组织结构,和一定的关系约束等等存放的,描述这种组织结构的信息,例如表结构,表约束,字段约束等等,就可以成为元数据。

C# 源代码由CLI生成中间语言,保留了描述类型信息,接口,继承关系,类成员的元数据。我们可以通过反射来获取这些信息,并且除了获取之外,还可以通过反射在运行时动态调用一个类型的成员(而不仅仅在编译时)

    • *

反射

System.Type

Type类是读取类型元数据信息的类,一个Type类的实例代表了目标类型的类型信息。

Type类表示类型声明,包括类类型、接口类型、数组类型、值类型、枚举类型、类型参数、泛型类型定义,以及开放或封闭构造的泛型类型。

Type 类定义在System命名空间下。

以下是Type类中的部分信息

属性说明
Assembly获得程序集
Attributes获得与类型关联的特性
BaseType获得基类型
FullName获得包括命名空间的类型名
Name获得当前成员的名称
Namespace获取Type的命名空间
Is—用于判断当前类型

注:
关于"Is—",包括:

  1. 判断是否是类: IsClass;
  2. 判断是否是枚举:IsEnum;
  3. 判断是否是接口:IsInterface;
  4. 判断是否是抽象的:IsAbstract;
  5. 判断是否是数组:IsArray;
  6. 判断可见性:IsPublic,IsSealled,IsVisible

‘’’'等等

方法说明
Assembly获得程序集
Attributes获得与类型关联的特性
BaseType获得基类型
FullName获得包括命名空间的类型名
Name获得当前成员的名称
Namespace获取Type的命名空间
Is—用于判断当前类型

如下代码,反射某个类型并输出其类型名称

            Type type = typeof(Type1);
            //获取名字
            Console.WriteLine(type.Name);
            //获取全称:包括命名空间
            Console.WriteLine(type.FullName);

更重要的是,通过这种方式可以动态引用类型成员,并进行赋值,读取,调用操作

            //获取方法
            Type1 typeinstance = new Type1();
            foreach (var item in type.GetMethods())
            {
                Console.WriteLine("方法:" + item.Name);
            }
            //为typeinstance赋值:
            type.GetProperty("StringProperty").SetValue(typeinstance, "hello 
reflect");
            Console.WriteLine("为typeinstance对象的属性StringProperty赋值:" + 
typeinstance.StringProperty);
            //调用方法
            string 
result=type.GetMethod("method").Invoke(typeinstance,null).ToString();
            Console.WriteLine("调用方法method得到的结果为:" + result);

例如:获取数据库某个表的数据时,通常会在代码中定义一个与该表对应的Model类。将读取到的datatable中的值一一赋给这个类是一件非常痛苦的事情(尤其是字段特别多的情况下)。
事实上,通常Model类并不会具有很多复杂的方法,而是定义仅仅定义一些字段。因此可以尝试将Model的属性字段和数据库中表的字段名称定义的完全相同,应用反射的方法进行赋值操作:

        public List<TESTTABLE> DateBaseHelper()

        {

            SqlConnection con = new SqlConnection("constr");
            string sql = "select *from TESTTABLE";
            SqlCommand cmd = new SqlCommand(sql,con);
            SqlDataAdapter da = new SqlDataAdapter(cmd);
            DataSet ds = new DataSet();
            da.Fill(ds);
            List<TESTTABLE> tests = new List<TESTTABLE>();
            Type type = typeof(TESTTABLE);
            PropertyInfo[] properties = type.GetProperties();

            for(int i=0;i<ds.Tables[0].Rows.Count;i++)
            {
                TESTTABLE test = new TESTTABLE();
                foreach (var item in properties)
                {
                    item.SetValue(test, ds.Tables[0].Rows[i][item.Name]);
                }
                tests.Add(test);
            }
            return tests;
        }

注意:虽然这样做非常省代码,但是要考虑到反射也是有成本的(可能会影响性能,但是具体影响是否很大我没有做过深入了解)。这里主要用意还是想证明:反射是非常有用的。


typeof

typeof是一个运算符,对某一个类型名称或类型的实例使用相当于执行了GetType()方法。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值