泛型类型、集合和对象引用

本文关键字:对象引用 集合 泛型类型 | 更新日期: 2023-09-27 18:07:35

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

不,我想在这些类实例上建立索引。我首先想到的是字典:Dictionary<int, GenericClass<Type1>>,这显然是行不通的。

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

泛型类型、集合和对象引用

在这种情况下,您通常要做的是创建一个通用的非泛型基类(有时是抽象类,或非泛型接口)GenericClass, GenericClass<Type_T>是从它派生出来的,并且它包含没有作为参数/返回类型的Type_T的方法。你使用这个基类/接口完全为你写的:Dictionary<int, GenericClass>

最后的竞争是:Dictionary<int, object>,因为object是。net中所有类类型的基类。

经典案例:List<T>源自IList, ICollection, IEnumerable

一个紧接xanatos回答的代码示例:

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);
    }
}

您还可以查看泛型中的协方差。

你还需要为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>>();

编辑:为了完整

你不能使用这个来传递ittype作为genericclass的参数。它需要逆变,使用逆变会破坏对Dictionary<int, IGenericClass<IType>> dict的赋值:

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

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

几乎与Hjalmar Z的答案相似,但变化是我使用了ObservableCollection而不是List。这可能会解决索引集合

的问题
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);
    }
}