考虑一下,我有以下方法:
public T Resolve<T>()
{
var targetType = typeof(T);
if (targetType.IsGenericType
&& targetType.GetGenerictTypeDefinition() == typeof(IEnumerable<>))
{
List<object> collection = this.ResolveCollection(targetType);
return (T)(object)collection;
}
return (T)this.ResolveSingle(targetType);
}
样本用法:
IEnumerable<IFoo> coll = myClass.Resolve<IEnumerable<IFoo>>();
很明显,由于协方差,示例会抛出无效投射的异常 - 尽管List<object>
包含IEnumerable<IFoo>
实现,但我们无法将collection
强制转换为IFoo
仅Resolve
。
在使用反射和非泛型方法时,是否有针对该问题的解决方法?我不想更改Cast
签名,因此我没有使用LINQ {{1}}的通用类型的项目。
答案 0 :(得分:1)
这将是丑陋的。您可以在&#34;制作&#34;之后调用Linq方法Enumerable.Cast<>
。它,即填写通用参数。
这是一个扩展方法:
public static TIEnumerable ToIEnumerable<TIEnumerable>(this IEnumerable<object> source)
{
var type = typeof(TIEnumerable);
if (!type.IsGenericType || type.GetGenericTypeDefinition() != typeof(IEnumerable<>))
throw new ArgumentException("Wrong type arg: " + type, "TIEnumerable");
var methOpen = typeof(Enumerable).GetMethod("Cast");
var methConstructed = methOpen.MakeGenericMethod(type.GenericTypeArguments[0]);
return (TIEnumerable)methConstructed.Invoke(null, new object[] { source, });
}
(您甚至可以扩展非通用IEnumerable
,因为Cast<>
对此进行操作。)
然后if
(在您的问题中)的正文可能是:
List<object> collection = this.ResolveCollection(targetType);
return collection.ToIEnumerable<T>();
如果你想要急切迭代并返回List<>
,那就是:
List<object> collection = this.ResolveCollection(targetType);
return collection.ToIEnumerable<T>()
.ToList();
答案 1 :(得分:0)
找到解决方法:
List<object> collection = this.ResolveCollection(targetType);
var itemType = targetType.GetGenericArguments()[0];
var listType = typeof(List<>).MakeGenericType(itemType);
var listInstance = Activator.CreateInstance(listType, new object[0]) as IList;
foreach (var instance in collection)
{
listInstance.Add(instance);
}
return (T)listInstance;
然后,施法就像一个chram。