繁体   English   中英

C# 泛型类型约束取决于使用的构造函数

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM