反射是什么,部分人可能会说,他可以动态获取类型对象,我当初也是那么想的,面试完了才发现,以前的理解比较粗浅,我又重新温习了次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)
{
........
}