簡體   English   中英

從具有運行時泛型類型的泛型方法中檢索集合

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM