C# 中反射的应用 和 代码中 is, as 分析

来源:互联网 发布:表白网站源码 编辑:程序博客网 时间:2024/05/16 09:19

反射是什么,部分人可能会说,他可以动态获取类型对象,我当初也是那么想的,面试完了才发现,以前的理解比较粗浅,我又重新温习了次MSDN上关于反射的说明,把自己的想法发到下面。

 

首先说明下,反射的类型是T,他是继承于System.Type.

 

它能干什么?

 

它封装了类型,它可以得到当前对象的类型(这其实是我当初的想法,只能说明它的一个功能)。

 

string reflectorString = "I'm a string".

System.Type type = reflectorString.GetType();

System.Console.WriteLine(type);

输出结果:

 

string

 

它封装了程序集合。

 

System.Reflection.Assembly o = System.Reflection.Assembly.Load("mscorlib.dll");
System.Console.WriteLine(o.GetName());

 

输出结果:mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

 

有人说你只能拿到他的类型和一些程序集信息,那怎么能算封装了它呢。我们看下面一个例子:

 

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Reflection;

    namespace RefelectorDemo
    {
        [System.AttributeUsage(System.AttributeTargets.Class |
                           System.AttributeTargets.Struct,
                           AllowMultiple = true)  // multiuse attribute
        ]
        public class Author : System.Attribute
        {
            string name;
            public double version;

            public Author(string name)
            {
                this.name = name;
                version = 1.0;  // Default value
            }

            public string GetName()
            {
                return name;
            }
        }

        [Author("H. Ackerman")]
        class FirstClass
        {
            // ...
        }

        // No Author attribute
        class SecondClass
        {
            // ...
        }

        [Author("H. Ackerman"), Author("M. Knott", version = 2.0)]
        class ThirdClass
        {
            // ...
        }

        class TestAuthorAttribute
        {
            static void Main()
            {
                PrintAuthorInfo(typeof(FirstClass));
                PrintAuthorInfo(typeof(SecondClass));
                PrintAuthorInfo(typeof(ThirdClass));
                Console.ReadLine();
            }

            private static void PrintAuthorInfo(System.Type t)
            {
                System.Console.WriteLine("Author information for {0}", t);
                System.Attribute[] attrs = System.Attribute.GetCustomAttributes(t);  // reflection

                foreach (System.Attribute attr in attrs)
                {

                    //if (attr is Author)
                    //{
                    //    Author a = (Author)attr;
                    //    System.Console.WriteLine("   {0}, version {1:f}", a.GetName(), a.version);
                    //}
                    Author author = attr as Author;
                    if (author != null)
                    {
                        System.Console.WriteLine("   {0}, version {1:f}", author.GetName(), author.version);
                    }
                }
               
            }
        }
    }

 

上面那个例子中,我们通过反射获取了Type类型的属性,然后通过于自定义类的比较,输出他的属性。

这下我们拿到了Name,和属性了.

 

回忆下我们刚才对T的操作。

string reflectorString = "I'm a string".

System.Type type = reflectorString.GetType();

 

System.Attribute[] attrs = System.Attribute.GetCustomAttributes(t);

 

反射不仅仅是可以拿到对象类型,其实它是对程序集和类型的一个封装。

 

还有一些比较有用的方法:

 

 

Assembly a = typeof(Object).Module.Assembly

 

MemberInfo[] memberinfo = typeof(System.IO.File).GetMembers();

 

.....................                                                             ......................

 

MemberInfo、MethodInfo、FieldInfo 和 PropertyInfo 等等,

 

综合上面说所的,反射封装了程序集,类型,它可以拿到所有的信息(method,attribute,property...),而不仅仅是拿到了当前的对象类型。

 

忘记is as 了。

 

is 是用来检查类型的,而且is 操作符是不会抛出异常的。

 

if(o is Employee) 

{


   Employee e 
= (Employee) o;
   
//在if语句中使用e
}

 

as 是用来。。。

看代码:

 

Employee e = o as Employee;

把一个引用对象看作是某一个对象类型,并将这个引用赋予另外一个引用对象,结果:

 

如果类型相同就给予一个非空的引用,不然就是null, 只检查一次。而上面的If语句的类型转化,也会导致1次类型检查,所以尽量使用As,这样提高了性能,只进行一次检查哈。

我们只要

if(e!=null)

{

........

}