通用类型,集合和对象引用

时间:2015-08-13 09:12:46

标签: c# generics

我有一个通用类型GenericClass<Type_T>(如果有帮助,Type_T实现IType_T。我创建了一些实例,例如GenericClass<Type1>GenericClass<Type2>

不,我想要一堆这些类实例的索引。 我首先想到的是一本字典:Dictionary<int, GenericClass<Type1>>这显然不起作用。

这个问题有解决方案吗?如何存储索引的泛型类型集合?

4 个答案:

答案 0 :(得分:6)

通常,在这种情况下你要做的是创建一个公共的非泛型基类(有时是一个抽象类,或一个非泛型接口)GenericClassGenericClass<Type_T>从中派生出来,包含Type_T作为参数/返回类型的方法。您完全根据自己编写的内容使用此基类/接口:Dictionary<int, GenericClass> ...

竞争对手是:Dictionary<int, object>,因为object是.NET中所有类类型的基类。

经典案例:List<T>派生自IListICollectionIEnumerable

答案 1 :(得分:3)

一个紧凑的代码示例,跟随xanatos&#39;回答:

interface IType { }
interface IGenericClass { }
class Type1 : IType { }
class Type2 : IType { }
class GenericClass<T> : IGenericClass where T : IType { }

class Program
{
    static void Main(string[] args)
    {
        var gen1 = new GenericClass<Type1>();
        var gen2 = new GenericClass<Type2>();
        var list = new List<IGenericClass>();
        list.Add(gen1);
        list.Add(gen2);
    }
}

答案 2 :(得分:2)

您还可以查看covariance in generics

您还需要为GenericClass定义一个通用接口,但它可以是通用的:

interface IType { }
interface IGenericClass<out T> where T : IType { }
class Type1 : IType { }
class Type2 : IType { }
class GenericClass<T> : IGenericClass<T> where T : IType { }

class Program
{
    static void Main(string[] args)
    {
         Dictionary<int, IGenericClass<IType>> dict = new Dictionary<int, IGenericClass<IType>>();
                dict[0] = new GenericClass<Type2>();
                dict[1] = new GenericClass<Type1>();
     }
}

但它不允许:

 Dictionary<int, IGenericClass<object>> dict = new Dictionary<int, IGenericClass<object>>();

编辑:完整性

您无法使用此功能将IType作为IGenericClass中的参数传递。它需要逆转并且使用逆变会将分配中断到Dictionary<int, IGenericClass<IType>> dict

  

协变类型参数用out关键字标出(Out关键字   在Visual Basic中,+为MSIL汇编程序)。你可以使用协变   type参数作为属于的方法的返回值   接口,或作为委托的返回类型。你不能使用   协变类型参数作为接口的泛型类型约束   方法

 interface IGenericClass<out T> where T : IType
 {
    T GetType(); //possible
    void SetType(T t); //not possible
 }

答案 3 :(得分:1)

与Hjalmar Z的答案几乎相似,但改变是代替List我使用了ObservableCollection。这可能会解决索引收集的问题

interface IType { }
interface IGenericClass { }
class Type1 : IType { }
class Type2 : IType { }
class GenericClass<T> : IGenericClass where T : IType { }

class Program
{
    static void Main(string[] args)
    {
        var gen1 = new GenericClass<Type1>();
        var gen2 = new GenericClass<Type2>();
        ObservableCollection<IGenericClass> GCClass = new ObservableCollection<IGenericClass>();
        GCClass.Add(gen1);
        GCClass.Add(gen2);
    }
}