起初我正在使用:
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);
...
我正在寻找能够完成上述行为的东西,但无需在界面中的所有不同属性中进行硬编码。
答案 0 :(得分:3)
您可以use Expression<T>
to pre-compile传递给OrderBy
的表达式。然后你可以在运行时查找它们。
答案 1 :(得分:2)
您使用的所有内容都不涉及硬编码的实际属性列表,将使用“幕后”反射。
答案 2 :(得分:1)
您可以创建一次PropertyInfo并使用它在多个目标对象上调用GetValue。这比为列表中的每个项调用TypeDescriptor.GetProperties要便宜得多。
另外,尝试删除AsParallel - 开销实际上可能会降低性能,而不是在这种情况下帮助它。
试试这个:
var prop = unsorted.GetType().GetGenericArguments()[0].GetProperty(firstSort.Item2);
sortedList = unsorted.OrderBy(myItem => prop.GetValue(myItem, null));
答案 3 :(得分:0)
如果您在班级中实施ICustomTypeDescriptor,那么在使用TypeDescriptor时可以避免反射。
当然,我假设您拥有myItem
的类型。
答案 4 :(得分:0)
最好的办法是使用Microsoft提供的Dynamic LINQ库。
答案 5 :(得分:0)
我喜欢Roger的答案最适合真正的解决方案,但是如果你想要一些简单的东西,你可以构建一个小代码生成器来获取类并将其属性分解为字符串到lambda的字典,代表每个属性。在运行时,您可以从此字典中调用以检索适当的lambda。
答案 6 :(得分:0)
您可以使用DLR。开源框架Impromptu-Interface在幕后完成所有dlr管道,并获取属性2.5x faster than reflection的值。
sortedList = unsorted.AsParallel().OrderBy(myItem => Impromptu.InvokeGet(myItem,firstSort.Item2));