繁体   English   中英

如何在不使用反射的情况下通过名称动态访问属性?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM