C#语法小知识(十)反射

来源:互联网 发布:淘宝达人的推广方式 编辑:程序博客网 时间:2024/05/17 09:22

反射指程序可以访问、检测和修改它本身状态或行为的一种能力。

反射(Reflection)有下列用途:

  • 它允许在运行时查看特性(attribute)信息。
  • 它允许审查程序集中的各种类型,以及实例化这些类型。
  • 它允许调用后期绑定的方法。
  • 它允许在运行时创建新类型,然后使用这些类型执行一些任务。


用途一:

查看特性(参考C#语法小知识(七)特性),例如下面,我们自定义了一个特性:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property)]public class TestAttribute: Attribute{public int val{ get; private set;}public TestAttribute(int i){val = i;}}
为类添加特性:
[Test(0)]class Test0{}
查看特性:

Test0 tmp = new Test0 ();Type t = tmp.GetType ();foreach (Attribute attr in t.GetCustomAttributes(true)) {if (attr is TestAttribute) {Console.WriteLine (((TestAttribute)attr).val);}}

用途二:

查询当前程序集的各种类型:

Assembly assembly = Assembly.GetExecutingAssembly ();System.Type[] ts = assembly.GetTypes(); foreach (var t in ts) {Console.WriteLine (t);}

实例化:

Test0 t0 = (Test0)assembly.CreateInstance ("Test0");

用途三:

调用后期绑定的方法,例如我们定义了一个类:

class TestClass{public void print(string str){Debug.Log (str);}public int i {get;set;}}

后期绑定调用方法:

System.Type testT = assembly.GetType ("TestClass");System.Object testO = assembly.CreateInstance ("TestClass");testT.InvokeMember("print", BindingFlags.InvokeMethod, System.Type.DefaultBinder, testO, new object[]{"A test"});

用途四:

运行时创建新类型和成员方法并执行:

AssemblyName assemblyName = new AssemblyName ("customAssembly");AssemblyBuilder assemblyBuilder = System.AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule ("Main");TypeBuilder typeBuilder = moduleBuilder.DefineType("Test",TypeAttributes.Public);MethodBuilder methodBuilder = typeBuilder.DefineMethod ("TestMethod", MethodAttributes.Public, null, null);ILGenerator il = methodBuilder.GetILGenerator();il.Emit(OpCodes.Ldstr,"TestMethod");il.Emit(OpCodes.Call,typeof(Console).GetMethod("WriteLine",new System.Type[]{typeof(string)}));il.Emit(OpCodes.Ret);System.Type customType = typeBuilder.CreateType ();System.Object customObject = customType.Assembly.CreateInstance (customType.Name);customType.InvokeMember (methodBuilder.Name, BindingFlags.InvokeMethod, System.Type.DefaultBinder, customObject, null);



优点:

  • 1、反射提高了程序的灵活性和扩展性。 
  • 2、降低耦合性,提高自适应能力。 
  • 3、它允许程序创建和控制任何类的对象,无需提前硬编码目标类。

缺点:

  • 1、性能问题:使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。因此反射机制主要应用在对灵活性和拓展性要求很高的系统框架上,普通程序不建议使用。 
  • 2、使用反射会模糊程序内部逻辑;程序员希望在源代码中看到程序的逻辑,反射却绕过了源代码的技术,因而会带来维护的问题,反射代码比相应的直接代码更复杂。

1 0
原创粉丝点击