在IEnumerable <t> </t>中获取T的类型

时间:2012-04-18 11:07:18

标签: c# generics .net-4.0 types

这是我的通用类:

public class MyClass<T>
{
    public T MainModel { get; set; }

    public Type GetType()
    {
        //here
    }
}

然后我用这种形式:

List<MySecondClass> Myinstance = new List<MySecondClass>();

MyClass<IEnumerable<MySecondClass>> mainInstance = new  MyClass<IEnumerable<MySecondClass>> { MainModel = Myinstance  };

所以我需要GetType()方法返回typeof(MySecondClass)您的建议是什么?

更新

我必须提一下,总是只用两种形式使用MyClass:第一种:我在上面完全编码,第二种:

ThirdClass thirdone = new ThirdClass(); 
MyClass<ThirdClass> = new MyClass<ThirdClass>(){ MainModel = thirdone};

3 个答案:

答案 0 :(得分:6)

如果TList<T>

// add error checking to taste
var typeOfEnumerable = typeof(T).GetInterfaces().Where(i => i.IsGenericType)
    .Single(i => i.GetGenericTypeDefinition() == typeof(IEnumerable<>))
    .GetGenericArguments().First();

<强> See it in action

如果TIEnumerable<T>

// add error checking to taste
var typeOfEnumerable = typeof(T).GetGenericArguments().First();

重要说明

你真的应该考虑MyClass在这里尝试做什么。为什么T成为IEnumerable<X>的特殊情况?也许应该在T添加一些约束?如果没有更具体的信息,就不可能回答这些问题和其他重要问题,但你真的应该这样做。

另外,您是否偶然或故意将方法命名为GetType?隐藏object.GetType就像真的,真的,真的不是一个好主意所以我建议你重命名这个方法。

答案 1 :(得分:2)

编辑:读得太快了。对不起。

var t = typeof(T);
if (t.IsGenericType)
{
    return t.GetGenericArguments().FirstOrDefault();
}

答案 2 :(得分:0)

考虑在许多不同情况下使用IEnumerable<T>

示例:

  • MyClass<IEnumerable<MySecondClass>>:正如您所说,您需要MySecondClass
  • MyClass<List<MySecondClass>>:您可能需要MySecondClass
  • MyClass<Dictionary<Guid, MySecondClass>>:还MySecondClass?或KeyValuePair<Guid, MySecondClass>
  • MyClass<MyOwnStringList>:MyOwnStringList将实现IEnumerabl<string>。类本身没有泛型参数。有很多例子。
  • MyClass<string>:您认为该字符串是否实现了IEnumerable<char>
  • 一个类可以实现多个IEnumerable<T>定义。

在考虑这些情况后,你必须决定做什么。

  • 您可以搜索IEnumerable<T>接口并提取通用参数。可能有一个以上。字符串可能有例外。
  • 您可能会放弃尝试获取IEnumerable<T>通用参数。
  • 您可能只想直接支持IEnumerable<T>(无子类型),例如IList<T>