我有一个通用方法
var propertyResolverMethod = _propertyResolver
.GetType()
.GetMethod(
nameof(_propertyResolver.GetEntities),
new[] { typeof(string), typeof(string) })
?.MakeGenericMethod(_itemType);
和调用
var recommendedItems = propertyResolverMethod
?.Invoke(
_propertyResolver,
new object[] { itemId, ResolvedCollectionId });
它在编译时返回一个对象,但是在运行时,它返回IQueryable<Item>
,该项目是_itemType的项目,我们仅在运行时才能找到其类型,但是我知道它具有一个集合我需要获取的Item.RelatedItems内部。已尝试将其强制转换为动态,但不适用于我的情况,我知道可以通过表达式解决。
应该是可迭代的
var itemIds = recommendedItems?.Select(i => i.RelatedItems.Select(s => s.ItemID));
但是没有适当的转换是不可能的
答案 0 :(得分:0)
嗯..
因此,如果我正确理解了您,您就会知道此方法将返回一个IQueryable<Item>
,其中Item
是先前存储在_itemType
中的类型,并且您也知道该类型始终会定义一个事实RelatedItems
依次是IEnumerable<T>
或IQueryable<T>
,其中T
定义了ItemID
?
是否存在所有可能的_itemTypes
都继承自RelatedItems
的类型?如果是这样,您可以尝试将其投射...
否则,您可以做更多反射魔术:
如果您知道结果是IQueryable<TItem>
,则可以使用Reflection提取RelatedItems
的属性获取器,然后将 that 传递给Select函数(可以通过投射到IQueryable<object>
或再次使用...反射。
但是说实话,这将是一种非常非常肮脏的方式,而我只会在万不得已的情况下这样做。
我现在的第一个本能是尝试重构包含的类(_itemType
提示我这是一个成员字段),所以它也是通用的(如果需要,可以从非通用类继承) ),因此该类通过其自己的type参数知道该类型。
另一种解决方案是具有以下功能:
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
,它会自动将内部枚举/可查询对象连接起来。
我希望这可以帮助您找到解决方案。