如何在不使用反射的情况下通过名称动态访问属性?
起初我使用:
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);
...
我正在寻找可以完成上述行为的东西,但不必在界面中的所有不同属性中进行硬编码。
At first I was using:
sortedList = unsorted.AsParallel().OrderBy(myItem => TypeDescriptor.GetProperties(myItem)[firstSort.Item2].GetValue(myItem));
Where firstSort.Item2 was the string name of the property. However, the performance degraded significantly as the number of items in the unsorted list increased. (As I expected)
Is there a way to do this without using reflection?
The brute force approach would be to do something like:
if(firstSort.Item2 == "Size")
sortedList = unsorted.AsParallel().OrderBy(myItem => myItem.Size);
else if(firstSort.Item2 == "Price")
sortedList = unsorted.AsParallel().OrderBy(myItem => myItem.Price);
...
I'm looking for something that would accomplish the above behavior, but without having to hardcode in all the different properties in the interface.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
我喜欢 Roger 的答案,这是真正的解决方案,但如果您想要简单的东西,您可以构建一个小型代码生成器来获取该类并将其属性分解为 lambda 字符串字典,代表每个属性。在运行时,您可以从此字典中调用来检索适当的 lambda。
I like Roger's answer the best for a true solution, but if you want something simple, you can build a small code generator to take the class and break out its properties into a dictionary of string to lambda, representing each property. At runtime, you could call from this dictionary to retrieve the appropriate lambda.
您可以使用 DLR。开源框架Impromptu-Interface 在幕后完成所有 dlr 管道工作,并获取属性值比反射快 2.5 倍。
You can use the DLR. The open source framework Impromptu-Interface does all the dlr plumbing behind the scenes and and gets the value of a property 2.5x faster than reflection.
您可以使用
Expression
预编译您传递给OrderBy
的表达式。然后您可以在运行时查找它们。You can use
Expression<T>
to pre-compile the expressions that you're passing toOrderBy
. Then you can look them up at runtime.您使用的所有不涉及实际属性的硬编码列表的内容都将在“幕后”使用反射。
Everything you use that doesn't involve a hard-coded list of actual properties, will be using Reflection "behind the scenes".
您可以创建一次 PropertyInfo,然后使用它对多个目标对象调用 GetValue。这比为列表中的每个项目调用 TypeDescriptor.GetProperties 要便宜得多。
另外,尝试删除 AsParallel - 在这种情况下,开销实际上可能会降低性能而不是帮助它。
试试这个:
You can create the PropertyInfo once and use it to call GetValue over multiple target objects. This will be much less expensive than calling TypeDescriptor.GetProperties for every item in the list.
Also, try removing AsParallel - the overhead may actually be reducing performance rather than helping it in this case.
Try this:
如果您在类中实现 ICustomTypeDescriptor ,那么您可以使用 TypeDescriptor 时避免反射。
当然,我假设您拥有
myItem
类型。If you implement ICustomTypeDescriptor in your class, then you can avoid the reflection when using TypeDescriptor.
Of course, I'm assuming you own the type of
myItem
.最好的选择是使用 Microsoft 提供的动态 LINQ 库。
这是一个链接:http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx< /a>
Your best bet is to use the Dynamic LINQ library provided by Microsoft.
Here is a link: http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx