.net反射存在的问题及优化技术--反射之动态调用方法的改进

.net反射存在的问题及优化技术--反射之动态调用方法的改进

2570发表于2015-03-16

如果要被调用的一个对象的方法或属性,要在运行的时候才明确,而不是在编译的时候就定好的,用反射可以轻松的实现,这里介绍一下.net反射在动态调用方法存在的问题及反射之动态调用方法的改进。比如下面的代码:


public void DynamicExecution()
{
    Type objType = Type.GetType("DynamicExecution.Test.DynamicClass");

    object obj = Activator.CreateInstance(objType);
    MethodInfo mInfo = objType.GetMethod("AddNumbers",
	new Type[] { typeof(int), typeof(int) });

    // 调用对象的方法AddNumbers
    mInfo.Invoke(obj, new object[] { 1, 5 });

    PropertyInfo pInfo = objType.GetProperty("ID");

    // 为obj对象的属性ID设置值
    pInfo.SetValue(obj, "TEST_ID", null );

} 


上面代码的缺点:

1、每次动态的调用一个方法或属性的代价都会比静态调用大几倍。

2、在编译的时候动态调用相关的方法参数和属性的傎的类型都没有得到安全检查,所以当传入不正确的类型的值时,只有在运行的时候才会被知道,这样运行的异常、报错是不会在编译的时候得到提前预知的。

3、静态调用在编译的时候编译器会为我们做一些优化,而动态调用不仅享受不了优化的好处的,而且也比静态调用代码更长,可维护性、可读性都大大的降低。

改进后的代码:


Public void OptimizedDynamicExecution()
{
    Type objType = Type.GetType("DynamicExecution.Test.DynamicClass");

    IDynamicClass obj = Activator.CreateInstance(objType) as IDynamicClass;

    if (null != obj)
    {
        int result = obj.AddNumbers(1, 5);
        obj.ID = 10; 
    }
}

// OptimizedDynamicExecution所要调用的的方法和属性封装成接口。
public interface IDynamicClass
{
    int ID { get; set; }

    int AddNumbers(int a, int b);
} 


OptimizedDynamicExecution所要调用的的方法和属性封装成接口。


上面代码的优点:

1、调用AddNumbers方法和静态调用速度几乎没有差别。

2、通过接口的形式实现了静态调用,传入的参数通过了编译时类型检查 。

3、提出的这个接口可以用在项目的其它地方,达到了代码复用。

4、方法的调用代码长度减少了,可维护性、可读性都大大的提高了。

小编蓝狐