背景:用户应该能够尽可能有效地合理地选择DB-table/model/class和filter/sort/sort/dishere there public属性。
可以通过Reflection-api查询名称,但是我想知道,这些访问是否可以存储并以这种方式变得更有效?
此示例显示了如何完成的,但是在每个访问中,它都会在func中查询反射-API。
public class TestClass // the Model or Table
{
public int Id { get; set; }
public string Name { get; set; }
}
public static void Main( string[] args )
{
var testClasses = new TestClass[] {
new TestClass { Id = 1 , Name = "1" } ,
new TestClass { Id = 2 , Name = "2" } ,
new TestClass { Id = 3 , Name = "3" } ,
};
var propertyInfos = typeof( TestClass ).GetProperties();
var map = new Dictionary<string,Func<object,object>>(); // Func<object,object> -> Func takes an instance of the class and return a public property
// load the map once
foreach( var propertyInfo in propertyInfos )
{
Func<object,object> func = x => propertyInfo.GetValue( x );
map.Add( propertyInfo.Name , func );
}
// get the names by user-input
var names = propertyInfos.Select( x => x.Name ).ToArray();
// load the properties by name
foreach( var testClass in testClasses )
{
Console.WriteLine( $"{testClass.Id} - {testClass.Name}" );
foreach( var name in names )
{
var func = map[ name ];
var value = func( testClass ); // this is 'bad' as it uses reflection every invokation
Console.WriteLine( $"t{name} = {value}" );
}
}
}
我的问题是:这个字典
可以吗var map = new Dictionary<string,Func<object,object>> {
{ "Id" , x => ( x as TestClass ).Id } ,
{ "Name" , x => ( x as TestClass ).Name } ,
};
仅通过提供类型来自动创建(并且不使用每个援引上的反射)?
您可以通过从每个呼叫中删除反射并仅执行一次来获得一些东西:
var par = Expression.Parameter(typeof(object), "row");
// load the map once
foreach (var propertyInfo in propertyInfos)
{
Func<object, object> func = Expression.Lambda<Func<object, object>>(Expression.Convert(Expression.Property(Expression.Convert(par, propertyInfo.DeclaringType), propertyInfo), typeof(object)), par).Compile();
map.Add(propertyInfo.Name, func);
}
i创建一个不同的小表达树,将参数对象投射到"正确"类型(在这种情况下为TestClass
),调用属性的Getter,然后将结果转换为object
。