Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在不使用反射的情况下按名称动态访问属性?_C#_Performance_Reflection_Dynamic_Properties - Fatal编程技术网

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

C# 如何在不使用反射的情况下按名称动态访问属性?,c#,performance,reflection,dynamic,properties,C#,Performance,Reflection,Dynamic,Properties,起初我使用的是: sortedList = unsorted.AsParallel().OrderBy(myItem => TypeDescriptor.GetProperties(myItem)[firstSort.Item2].GetValue(myItem)); 其中firstSort.Item2是属性的字符串名称。但是,随着未排序列表中项目数量的增加,性能显著降低。(如我所料) 有没有一种不使用反射的方法可以做到这一点 蛮力方法将采取如下措施: if(firstSort.Item

起初我使用的是:

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);
...

我正在寻找能够实现上述行为的东西,但不必硬编码接口中的所有不同属性。

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

如果您在类中实现,然后在使用TypeDescriptor时可以避免反射


当然,我假设您拥有
myItem
的类型,您可以使用传递给
OrderBy
的表达式。然后您可以在运行时查找它们。

您最好使用Microsoft提供的动态LINQ库


这里有一个链接:

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

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

试试这个:

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

对于真正的解决方案,我喜欢Roger的答案,但是如果您想要一些简单的东西,您可以构建一个小型代码生成器来获取类,并将其属性分解到一个字符串到lambda的字典中,表示每个属性。在运行时,您可以从此字典中调用以检索相应的lambda。

您可以使用DLR。开源框架在幕后执行所有dlr管道,并获取属性的值


您是否尝试过在OrderBy之外以及在OrderBy中使用TypeDescriptor.GetProperties(myItem)[firstSort.Item2].GetValue(myItem)后使用它?第二种解决方案的速度要快多少?是的,但我不想每次访问该属性时都进行反思。有没有一种方法可以让我决定使用反射访问哪个属性,然后让它排序,而不必每次都获取值?@Chris:GetValue是获取属性值的方式。因为每个对象都不同,所以必须为每个对象调用它。好的,我想我应该澄清一下……如何才能最大限度地减少使用反射对性能的影响。性能是一个实际问题吗?或者这是一个可感知的问题?你分析过了吗?当然!列表中最多有1000万个项目…反射访问是这种类型的热门途径。我尝试了这种方法…性能有了一点改进,但仍然非常缓慢。尽管如此,阿斯帕莱尔绝对值得。当列表中的项目超过100万个时,我会得到2-5倍的加速。我想这可能会给我的场景带来最好的结果。现在调查一下。
sortedList = unsorted.AsParallel().OrderBy(myItem => Impromptu.InvokeGet(myItem,firstSort.Item2));