[英]How can I access a property dynamically by name without using reflection?
起初我在使用:
sortedList = unsorted.AsParallel().OrderBy(myItem => TypeDescriptor.GetProperties(myItem)[firstSort.Item2].GetValue(myItem));
其中firstSort.Item2是属性的字符串名称。 但是,由于未排序列表中项目的数量增加,因此性能显着下降。 (如我所料)
有没有一种方法可以不用反射呢?
蛮力方法将做如下事情:
if(firstSort.Item2 == "Size")
sortedList = unsorted.AsParallel().OrderBy(myItem => myItem.Size);
else if(firstSort.Item2 == "Price")
sortedList = unsorted.AsParallel().OrderBy(myItem => myItem.Price);
...
我正在寻找可以完成上述行为的东西,而不必在接口中的所有不同属性中进行硬编码。
您可以使用Expression<T>
来预编译要传递给OrderBy
的表达式。 然后,您可以在运行时查找它们。
您使用的所有不涉及实际属性的硬编码列表的内容,都将在“幕后”使用“反射”。
您可以一次创建PropertyInfo,并使用它在多个目标对象上调用GetValue。 这将比为列表中的每个项目调用TypeDescriptor.GetProperties便宜得多。
另外,请尝试删除AsParallel-这种情况下的开销实际上可能会降低性能,而不是有所帮助。
尝试这个:
var prop = unsorted.GetType().GetGenericArguments()[0].GetProperty(firstSort.Item2);
sortedList = unsorted.OrderBy(myItem => prop.GetValue(myItem, null));
如果在类中实现ICustomTypeDescriptor ,则可以避免在使用TypeDescriptor时进行反思。
当然,我假设您拥有myItem
的类型。
最好的选择是使用Microsoft提供的Dynamic LINQ库。
这是链接: http : //weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
我喜欢Roger的最佳答案,它是一个真正的解决方案,但是,如果您想要简单的东西,则可以构建一个小的代码生成器来接收该类,并将其属性分解为lambda的字符串字典,以表示每个属性。 在运行时,您可以从此字典中调用以检索适当的lambda。
您可以使用DLR。 开源框架Impromptu-Interface在后台进行所有dlr处理,并且获得属性值的速度比反射速度快2.5倍 。
sortedList = unsorted.AsParallel().OrderBy(myItem => Impromptu.InvokeGet(myItem,firstSort.Item2));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.