当前位置:编程学习 > C#/ASP.NET >>

.NET Reflection optimization 反射优化

简介
反射是 Microsoft .NET framework 中非常强大的特性,它在 System.Reflection 命名空间中提供了一整套在运行时动态载入/处理程序集的 API。

反射 (Reflection) 如此强大,但仍需谨慎使用,因为它实际上是一种用性能换扩展性的一种方法,这里提供了一些优化反射的方法,以期把对性能的影响最小化。

场景1(动态调用一个方法)
一个标准且完整的动态调用方法示例
[csharp]  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) }); 
 
    // 动态调用 obj 对象上的 AddNumbers 方法  
    mInfo.Invoke(obj, new object[] { 1, 5 }); 
 
    PropertyInfo pInfo = objType.GetProperty("TEST_ID"); 
 
    // 动态设置 obj 对象的 ID 属性  
    pInfo.SetValue(obj, "TEST_ID", null ); 
}  

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) });

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

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

    // 动态设置 obj 对象的 ID 属性
    pInfo.SetValue(obj, "TEST_ID", null );
} 缺点:
每次动态调用方法(或属性)将比静态调用方式慢好几倍
编译时方法/属性的传入参数的类型安全性无法检查,在运行时传入错误数据/类型就会挂掉
编码量大,且可读性不高
优化代码
[csharp] Public void OptimizedDynamicExecution() 

    Type objType = Type.GetType("DynamicExecution.Test.DynamicClass"); 
 
    IDynamicClass obj = Activator.CreateInstance(objType) as IDynamicClass; 
 
    if (null != obj) 
    { 
        // 静态调用 obj 对象上的 AddNumbers 方法  
        int result = obj.AddNumbers(1, 5); 
 
        // 静态设定 obj 对象的 ID 属性  
        obj.ID = 10;  
    } 

 
// 在 OptimizedDynamicExecution API 中使用的 Inte易做图ce  
public inte易做图ce IDynamicClass 

    int ID { get; set; } 
    int AddNumbers(int a, int b); 
}  

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

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

    if (null != obj)
    {
        // 静态调用 obj 对象上的 AddNumbers 方法
        int result = obj.AddNumbers(1, 5);

        // 静态设定 obj 对象的 ID 属性
        obj.ID = 10;
    }
}

// 在 OptimizedDynamicExecution API 中使用的 Inte易做图ce
public inte易做图ce IDynamicClass
{
    int ID { get; set; }
    int AddNumbers(int a, int b);
} 改进点
静态调用提高了执行速度
引入一个 inte易做图ce 实现了类型安全
该 inte易做图ce 能在其他场景使用
更短的代码,更好的可读性
场景2(读取自定义属性custom attributes)
标准代码示例
[csharp]  [Table(Name="Employees")] 
public class Employee : Entity 

    [PrimaryKey] 
    public int Id { get; set; } 
     
    public string Name { get; set; } 
    public string Address { get; set; } 
    public DateTime DOB { get; set; } 
 

 
public class Entity 

    public Entity() 
    { 
        Type curType = this.GetType(); 
 
        object[] tableAttributes = curType.GetCustomAttributes(typeof(TableAttribute), true); 
 
        if(null != tableAttributes && tableAttributes.Count() > 0) 
        { 
            // Retrieve the attribute information  
        } 
        // Use the attribute information here   
    } 

[Table(Name="Employees")]
public class Employee : Entity
{
    [PrimaryKey]
    public int Id { get; set; }
   
    public string Name { get; set; }
    public string Address { get; set; }
    public DateTime DOB { get; set; }

}

public class Entity
{
    public Entity()
    {
        Type curType = this.GetType();

        object[] tableAttributes = curType.GetCustomAttributes(typeof(TableAttribute), true);

        if(null != tableAttributes && tableAttributes.Count() > 0)
        {
            // Retrieve the attribute information
        }
        // Use the attribute information here
    }
}以上定义了一个 Employee 实体类,对应数据库中的表明为 “Employees”,另外它的 Id 属性标记了一个 PrimaryKey 属性。
为了获取这些定义在 custom attributes 中的信息,在父类中使用了反射。

缺点
每次实例化都通过反射来获取 custom attributes 信息
通过反射来获取 custom attributes 信息是个“重活”
优化代码
[csharp] // 追加一个 C# 结构来存储信息  
public struct TableInfo 

    public string TableName; 
    public string PrimaryKey; 

 
public class Entity 

    private static Dictionary<Type, TableInfo> tableInfoList = new Dictionary<Type, TableInfo>(); 
 
    public Entity() 
    { 
        Type curType = this.GetType(); 
        TableInfo curTableInfo; 
      &n

补充:软件开发 , C# ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,