当前位置:  开发笔记 > 编程语言 > 正文

带有"专用"构造函数的C#Generic Class

如何解决《带有"专用"构造函数的C#GenericClass》经验,为你挑选了1个好方法。

我有一个类如下:

public class DropDownControl : BaseControl
    where Key: IComparable
{
    private IEnumerable mEnumerator;
    private Func mGetKey;
    private Func mGetValue;
    private Func mIsKeyInCollection;

    public DropDownControl(string name, IEnumerable enumerator, Func getKey, Func getValue, Func isKeyInCollection)
        : base(name)
    {
        mEnumerator = enumerator;
        mGetKey = getKey;
        mGetValue = getValue;

        mIsKeyInCollection = isKeyInCollection;
    }

我想为词典添加一个便利功能(因为它们可以自己有效地支持所有操作).

但问题是这样的构造函数只能直接指定Key和Value而不是T,但T只是KeyValuePair.有没有办法告诉编译器这个构造函数T是KeyValuePair,如:

public DropDownControl>(string name, IDictionary dict) { ... }

目前我使用静态Create函数作为变通方法,但我想要一个更好的直接构造函数.

public static DropDownControl, DKey, DValue> Create(string name, IDictionary dictionary)
            where DKey: IComparable
        {
            return new DropDownControl, DKey, DValue>(name, dictionary, kvp => kvp.Key, kvp => kvp.Value, key => dictionary.ContainsKey(key));
        }

Marc Gravell.. 13

不,基本上.非泛型类中的静态方法(例如DropDownControl [no <>])是最好的方法,因为在调用Create()时应该能够使用类型推理 - 即

var control = DropDownControl.Create(name, dictionary);

C#3.0在这里通过"var"(非常欢迎这里)和大大改进的泛型类型推理规则来帮助.在一些(更一般)的情况下,另一个类似的选项是扩展方法,但是从字典创建非常特定的控件的扩展方法感觉不太自然 - 我使用非扩展方法.

就像是:

public static class DropDownControl
{
    public static DropDownControl, TKey, TValue>
            Create(IDictionary value, string name)
    where TKey : IComparable
    {
        return new DropDownControl, TKey, TValue>
            (name, value, pair => pair.Key, pair => pair.Value,
            key => value.ContainsKey(key)
        );
    }
}

另一个选择是继承,但我不喜欢它...

public class DropDownControl :
    DropDownControl, TKey, TValue>
    where TKey : IComparable
{
    public DropDownControl(IDictionary lookup, string name)
        : base(name, lookup, pair => pair.Key, pair => pair.Value,
            key => lookup.ContainsKey(key)) { }
}

这增加了复杂性并降低了你的灵活性......我不会这样做......

总的来说,听起来你只想使用IDictionary <,> - 我想知道你是否不能简化你的控制只是使用它,并强制非字典调用者将自己包装在IDictionary <,> Facade中?



1> Marc Gravell..:

不,基本上.非泛型类中的静态方法(例如DropDownControl [no <>])是最好的方法,因为在调用Create()时应该能够使用类型推理 - 即

var control = DropDownControl.Create(name, dictionary);

C#3.0在这里通过"var"(非常欢迎这里)和大大改进的泛型类型推理规则来帮助.在一些(更一般)的情况下,另一个类似的选项是扩展方法,但是从字典创建非常特定的控件的扩展方法感觉不太自然 - 我使用非扩展方法.

就像是:

public static class DropDownControl
{
    public static DropDownControl, TKey, TValue>
            Create(IDictionary value, string name)
    where TKey : IComparable
    {
        return new DropDownControl, TKey, TValue>
            (name, value, pair => pair.Key, pair => pair.Value,
            key => value.ContainsKey(key)
        );
    }
}

另一个选择是继承,但我不喜欢它...

public class DropDownControl :
    DropDownControl, TKey, TValue>
    where TKey : IComparable
{
    public DropDownControl(IDictionary lookup, string name)
        : base(name, lookup, pair => pair.Key, pair => pair.Value,
            key => lookup.ContainsKey(key)) { }
}

这增加了复杂性并降低了你的灵活性......我不会这样做......

总的来说,听起来你只想使用IDictionary <,> - 我想知道你是否不能简化你的控制只是使用它,并强制非字典调用者将自己包装在IDictionary <,> Facade中?

推荐阅读
携手相约幸福
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有