簡體   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