.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# ,