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

发布于 2024-10-17 20:00:39 字数 580 浏览 1 评论 0原文

起初我使用:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

我不在是我 2024-10-24 20:00:40

我喜欢 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.

芸娘子的小脾气 2024-10-24 20:00:40

您可以使用 DLR。开源框架Impromptu-Interface 在幕后完成所有 dlr 管道工作,并获取属性值比反射快 2.5 倍。

sortedList = unsorted.AsParallel().OrderBy(myItem => Impromptu.InvokeGet(myItem,firstSort.Item2));

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.

sortedList = unsorted.AsParallel().OrderBy(myItem => Impromptu.InvokeGet(myItem,firstSort.Item2));
月竹挽风 2024-10-24 20:00:39

您可以使用Expression预编译您传递给 OrderBy 的表达式。然后您可以在运行时查找它们。

You can use Expression<T> to pre-compile the expressions that you're passing to OrderBy. Then you can look them up at runtime.

笑看君怀她人 2024-10-24 20:00:39

您使用的所有不涉及实际属性的硬编码列表的内容都将在“幕后”使用反射。

Everything you use that doesn't involve a hard-coded list of actual properties, will be using Reflection "behind the scenes".

我不吻晚风 2024-10-24 20:00:39

您可以创建一次 PropertyInfo,然后使用它对多个目标对象调用 GetValue。这比为列表中的每个项目调用 TypeDescriptor.GetProperties 要便宜得多。

另外,尝试删除 AsParallel - 在这种情况下,开销实际上可能会降低性能而不是帮助它。

试试这个:

var prop = unsorted.GetType().GetGenericArguments()[0].GetProperty(firstSort.Item2);
sortedList = unsorted.OrderBy(myItem => prop.GetValue(myItem, null));

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:

var prop = unsorted.GetType().GetGenericArguments()[0].GetProperty(firstSort.Item2);
sortedList = unsorted.OrderBy(myItem => prop.GetValue(myItem, null));
眼泪也成诗 2024-10-24 20:00:39

如果您在类中实现 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.

懷念過去 2024-10-24 20:00:39

最好的选择是使用 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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文