反思获取列表&lt;&gt;来自List <t>(来自通用容器类型的容器类型)

时间:2016-11-09 09:24:10

标签: c# generics reflection collections .net-4.5

我有一种特殊的情况,在一个反射器中,我可以得到不同类型的容器,我需要重新定义(比如制作克隆)。当引入新类型的容器(ObservableCollection<T>

时,这种情况就开始发生了

在克隆机制中我发现的是:

if (property.PropertyType.FullName.Contains(ReflectorResources.ListName) || property.PropertyType.FullName.Contains("ConcurrentBag"))
{
    var listElementType = property.PropertyType.GenericTypeArguments[0];
    var newList = (property.PropertyType.FullName.Contains(ReflectorResources.IncidentListName))
         ? Activator.CreateInstance(typeof(Definitions.Session.Products.Motor.IncidentList<>).MakeGenericType(listElementType))
         : property.PropertyType.FullName.Contains("ConcurrentBag") ? Activator.CreateInstance(typeof(ConcurrentBag<>).MakeGenericType(listElementType)) : Activator.CreateInstance(typeof(List<>).MakeGenericType(listElementType));    
    var oneItem = Activator.CreateInstance(listElementType);
}

所以我试着改写它:

if (new[] { ".Collections." }.Any(o => property.PropertyType.FullName.Contains(o)))
{
    var listElementType = property.PropertyType.GenericTypeArguments[0];
    var listType = property.PropertyType;
    var constructedListType = listType.MakeGenericType(listElementType);
    var newList = Activator.CreateInstance(constructedListType);
    var oneItem = Activator.CreateInstance(listElementType);
}

然而它突然爆炸:var constructedListType = listType.MakeGenericType(listElementType);错误

  

System.InvalidOperationException:只能在Type.IsGenericParameter为true的Type上调用方法。

我的猜测是我需要从List<> ...

中提取List<Something>类型

如何从通用容器类型中获取容器类型?

2 个答案:

答案 0 :(得分:2)

而不是:

var listElementType = property.PropertyType.GenericTypeArguments[0];
var listType = property.PropertyType;
var constructedListType = listType.MakeGenericType(listElementType);

试试这个:

Type listElementType = property.PropertyType.GenericTypeArguments[0];
Type constructedListType;
if (! property.PropertyType.IsGenericTypeDefinition)
    constructedListType = property.PropertyType;
else
{
    // Depending on where your property comes from
    // This should not work in the case the property type is List<T>
    // How listElementType should allow you to instantiate your type ?
    var listType = property.PropertyType.GetGenericTypeDefinition();
    constructedListType = listType.MakeGenericType(listElementType);
}

我还说你应该看看GetGenericTypeDefinition()方法,但在我写完这篇文章之前已经有了AakashM的答案。
然后你应该看看他的回答。

答案 1 :(得分:1)

我将引用this answer,它可能回答你对反思和泛型的任何问题:

  

要在运行时从构造类型获取未绑定类型,您可以   使用Type.GetGenericTypeDefinition method

Type listOfInt = typeof(List<int>);
Type list = listOfInt.GetGenericTypeDefinition(); // == typeof(List<>)
相关问题