C#确定泛型类型

时间:2010-05-27 17:34:55

标签: c# generics reflection types

我有几个模板化对象都实现了相同的接口:

MyObject<datatype1> obj1;
MyObject<datatype2> obj2;
MyObject<datatype3> obj3;

我想将这些对象存储在List中...我想我会这样做:

private List<MyObject<object>> _myList;

然后我想创建一个函数,它接受一个参数,作为数据类型,以查看我的列表中是否存在使用该数据类型的对象.... sorta无能为力。在伪代码中它将是:

public bool Exist(DataType T)
{
   return (does _myList contain a MyObject<T>?);
}

一些澄清......

我的界面是IMyObject<T>,我的对象是MyObject<T>。我有一个新课程MyObjectManager,我需要在其中存储MyObject<T>列表。我需要一个函数来检查该列表中是否存在MyObject<T>。类型T是使用T4 ....我的实体数据模型中的POCO类自动生成的数据类型。

3 个答案:

答案 0 :(得分:6)

您可以制作通用功能:

public bool Exists<T>() where T : class {
    return _myList.OfType<MyObject<T>>().Any();
}

请注意,这要求您在编译时知道T

如果您在运行时只拥有System.Type个对象,则需要使用反射:

public bool Exists(Type t) {
    var objectOfT = typeof(MyObject<>).MakeGenericType(t);

    return _myList.Any(o => o.GetType() == objectOfT);
}

但请注意,List<MyObject<object>> 无法持有MyObject<SomeType>
您需要将列表更改为List<object>,或使MyObject实现或继承非泛型类型,并使列表包含该类型。

答案 1 :(得分:1)

扩展方法怎么样?

public static bool HasAny(this IEnumerable source, Type type) {
    foreach (object item in source)
        if (item != null && item.GetType().Equals(type))
            return true;

    return false;
}

用法:

bool hasDataType1 = myList.HasAny(typeof(MyObject<datatype1>));

请注意,如果您不想输入typeof(...) - 也就是说,如果您基本上希望Exist方法关注类型对象MyObject<T>,我会选择SLaks的回答:

public static bool Exist<T>(this IEnumerable source) {
    return source.OfType<MyObject<T>>().Any();
}

另外,SLaks是正确的,你真的不能拥有除List<MyObject<object>>类型的对象或某些派生类(和MyObject<object>等等以外的任何东西的MyObject<datatype1>派生自MyObject<object> - 泛型无法正常工作。)

我可能建议的另一种解决方法是“你不能使用System.Type对象而不使用反射”来解决泛型类的类型问题:将MyObject<T>实现非通用接口,如下所示:

public interface IMyObject {
    Type DataType { get; }
}

public class MyObject<T> : IMyObject<T>, IMyObject {
    public Type DataType {
        get { return typeof(T); }
    }
}

然后您的列表可能是List<IMyObject>(非通用界面),您的Exist方法可能如下所示:

public static bool Exist<T>(this IEnumerable source, Type type) {
    return source.OfType<IMyObject>().Any(x => x.DataType.Equals(type));
}

答案 2 :(得分:0)

由于它们都实现了相同的接口,而不是将它们转换为对象并调用GetType(这可能很昂贵)为什么不在接口中添加一个名为class name(或者其他东西)的属性?然后你可以使用linq来获取该属性。不要忘记using System.Linq

using System.Linq;

public bool Exist(List<IMyInterface> objects, IMyInterface typeToCheck)
{
   return objects.Any(t => t.ObjectName == typeToCheck.ObjectName);
}