我有一个泛型类A,另一个类B处理A的实例并包含一些额外的数据。我需要有两个单独的类。 B不能从A继承,因为A有其他衍生物,B需要包含对A的引用。
作为一个简单的例子,我想写的是这个(字典是A,dicthandler是B):
class dicthandler<T> where T : Dictionary<Tk, Tv>
但是它没有编译,我需要指定所有类型参数:
class dicthandler<T, Tk, Tv> where T : Dictionary<Tk, Tv>
但我实际上并不关心Tk和Tv是什么,所以它们完全是冗余的,我只需要T.每当我想创建一个新实例时,我需要为构造函数指定所有类型参数,这会伤害我
显然我需要一些技巧。有什么想法吗?
答案 0 :(得分:5)
不,没有办法做到这一点。 DictHandler
的任何实例都必须知道T
的确切类型,包括TKey
和TValue
的类型。
如果您实际拥有相关字典的实例,则可以使用类型推断来减少显式指定类型参数的频率。例如:
public static class DictHandler
{
public static DictHandler<T, TKey, TValue> CreateHandler<T, TKey, TValue>
(T dictionary1, Dictionary<TKey, TValue> dictionary2)
where T : Dictionary<TKey, TValue>
{
return new DictHandler<T, TKey, TValue>();
}
}
public class DictHandler<T, TKey, TValue> where T : Dictionary<TKey, TValue>
{
}
然后像这样创建:
Dictionary<string, int> dict = new Dictionary<string, int>();
var handler = DictHandler.CreateHandler(dict, dict);
我相信你必须拥有这两个参数的原因是,参数(在类型推断中使用的所有参数)最终与直接提及类型参数的参数相对应。我不完全确定 - 这肯定有些难看。
另一种方法是为A创建一个基本类型或基本接口,其中不是泛型。例如,在这种情况下(假设我们可以控制字典),我们创建:
public interface INonGenericDictionary
{
// Members which don't rely on the type parameters
}
public class Dictionary<TKey, TValue> : INonGenericDictionary
{
...
}
然后
public class DictHandler<T> where T : INonGenericDictionary
{
...
}
我们无法确定这是否适用于您的情况,但可能。
答案 1 :(得分:2)
在对象构建方面,当前的C#要求你非常具体。不过,这似乎不太常见,所以你可以从当前类型的类型参数创建一个CreateDictHandler
类型:
private dicthandler<T, Tk, Tv> CreateDictHandler() {...}
...
var handler = CreateDictHandler();
如果类型参数用于方法,则必须为构造函数提供它们,但您仍然可以在变量声明中使用var
。
你可能也发现在很多情况下太多泛型实际上是一件坏事。如果它开始变得过于粗糙,有时像IDictionary
(非泛型)这样的东西是真正需要的。
答案 2 :(得分:1)
您不能省略键和值类型参数,因为它们是泛型类型签名的一部分。但您考虑过将类型定义更改为此吗?
class dicthandler<TKey, TValue>
然后您可以使用Dictionary<TKey, TValue>
类型。很明显,你的类型只能用于字典,所以不需要强制将这种类型作为泛型参数传递,因为你已经知道它是什么。