[英]C# generic type constraint depending on used constructor
我想模仿collections.defaultdict
中的 Python collections.defaultdict。 只要值类型具有无参数构造函数,以下内容就可以正常工作:
public class DefaultDictionary<TKey, TValue> : Dictionary<TKey, TValue> where TValue : new()
{
public new TValue this[TKey key]
{
get
{
TValue val;
if (!TryGetValue(key, out val)) {
val = new TValue();
Add(key, val);
}
return val;
}
set { base[key] = value; }
}
}
但是如果我想使用一个以键为参数的构造函数呢? 或者一般来说,一个工厂 function ,给定键,返回值类型的实例?
public class DefaultDictionary<TKey, TValue> : Dictionary<TKey, TValue> where TValue : new()
{
private readonly Func<TKey, TValue> factory;
public DefaultDictionary() : this(key => new TValue())
{}
public DefaultDictionary(Func<TKey, TValue> factory)
{
this.factory = factory;
}
public new TValue this[TKey key]
{
get
{
TValue val;
if (!TryGetValue(key, out val)) {
val = factory(key);
Add(key, val);
}
return val;
}
set { base[key] = value; }
}
}
现在的问题是,即使使用工厂 function,仍然需要TValue
具有无参数构造函数。 如果Thingy
没有无参数构造函数,则以下内容将无法编译:
new DefaultDictionary<int, Thingy>(key => new Thingy(key, otherStuff, moreStuff));
但是,删除约束将在new TValue()
语句中导致错误 CS0304。
直觉上,我想将类型约束放在DefaultDictionary()
构造函数上,但我怀疑这是可能的。 C#中是否有解决此问题的正确方法?
一种方法是只保留构造函数在DefaultDictionary
中采用值工厂,并创建一个具有: new()
约束的子类,并将无参数构造函数移到那里:
public class DefaultDictionaryParameterless<TKey, TValue> :
DefaultDictionary<TKey, TValue> where TValue : new()
{
public DefaultDictionaryParameterless()
: base(x => new TValue())
{
}
}
public class DefaultDictionary<TKey, TValue> : Dictionary<TKey, TValue>
{
private readonly Func<TKey, TValue> factory;
public DefaultDictionary(Func<TKey, TValue> factory)
{
this.factory = factory;
}
...
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.