泛型类型、集合和对象引用
本文关键字:对象引用 集合 泛型类型 | 更新日期: 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);
}
}