[英]Retrieving a collection from a generic method with a run time generic type
我有一個通用方法
var propertyResolverMethod = _propertyResolver
.GetType()
.GetMethod(
nameof(_propertyResolver.GetEntities),
new[] { typeof(string), typeof(string) })
?.MakeGenericMethod(_itemType);
和調用
var recommendedItems = propertyResolverMethod
?.Invoke(
_propertyResolver,
new object[] { itemId, ResolvedCollectionId });
它在編譯時返回一個 object,但在運行時,它返回IQueryable<Item>
這個項目是來自 _itemType 的項目,我們只在運行時發現它的類型,但我知道它在 Item.RelatedItems 中有一個集合我需要得到的。 已經嘗試過轉換為動態,但不適用於我的情況,我知道這可以通過表達式以某種方式解決。
應該像這樣可迭代
var itemIds = recommendedItems?.Select(i => i.RelatedItems.Select(s => s.ItemID));
但如果沒有適當的演員表,這是不可能的
唔..
因此,如果我理解正確,您知道此方法返回IQueryable<Item>
其中Item
是先前存儲在_itemType
中的類型,並且您還知道該類型始終定義RelatedItems
反過來又是IEnumerable<T>
或IQueryable<T>
與T
定義ItemID
?
是否存在所有可能的_itemTypes
都繼承RelatedItems
定義 RelatedItems 的類型? 如果是這樣,你可以嘗試投射到那個......
否則你可以做更多反射魔法:如果你知道你的結果是一個IQueryable<TItem>
RelatedItems
你可以用反射提取相關項目的屬性獲取器並將它傳遞給選擇函數(你可以通過轉換為IQueryable<object>
或通過使用...再次...反射。
但老實說,這將是一種非常非常骯臟的方式,我只會作為最后的手段。
我現在的第一個直覺是嘗試重構包含 class ( _itemType
向我暗示這是一個成員字段),所以它也是通用的(如果需要,從非通用 class 繼承),所以 ZBCBBA42F2ED4F8EBC40知道類型通過它自己的類型參數。
另一種解決方案是有一個像這樣的 function :
private <Type of itemIDs> GetRelatedItemIds<TItem>(object source) {
return ((IQueriable<TItem>)source)?.Select(i => i.RelatedItems.Select(s => s.ItemID));
}
現在通過反射獲取該方法並在其上使用MakeGenericMethod(_itemType)
,然后使用您的結果調用它。
請注意,您當前的選擇將返回一個嵌套的可枚舉/可查詢,其中每個條目都是 ItemID 的列表。 如果您不想這樣做,請使用SelectMany
而不是第一個Select
,它將自動連接內部可枚舉/可查詢。
我希望這可以幫助您找到解決方案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.