我有一个通用类型GenericClass<Type_T>
(如果有帮助,Type_T
实现IType_T
。我创建了一些实例,例如GenericClass<Type1>
,GenericClass<Type2>
。
不,我想要一堆这些类实例的索引。
我首先想到的是一本字典:Dictionary<int, GenericClass<Type1>>
这显然不起作用。
这个问题有解决方案吗?如何存储索引的泛型类型集合?
答案 0 :(得分:6)
通常,在这种情况下你要做的是创建一个公共的非泛型基类(有时是一个抽象类,或一个非泛型接口)GenericClass
,GenericClass<Type_T>
从中派生出来,包含Type_T
作为参数/返回类型的方法。您完全根据自己编写的内容使用此基类/接口:Dictionary<int, GenericClass>
...
竞争对手是:Dictionary<int, object>
,因为object
是.NET中所有类类型的基类。
经典案例:List<T>
派生自IList
,ICollection
,IEnumerable
。
答案 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);
}
}