如何从字典类继承?

23

我希望拥有Dictionary<TKey,TValue>的所有功能,但是我希望它表现为Foo<TKey,TValue>
我该如何实现这个目标?
目前我正在使用

class Foo<TKey,TValue> : Dictionary<TKey, TValue>
{   
    /*
     I'm getting all sorts of errors because I don't know how to 
     overload the constructors of the parent class.
    */
    // overloaded methods and constructors goes here.

    Foo<TKey,TValue>():base(){}
    Foo<TKey,TValue>(int capacity):base(capacity){}

}

如何正确地重载父类的构造函数和方法?

注意:我认为我误用了“overload”这个词,请纠正或建议更正。


1
你在我的回答评论中说这是装饰器模式的实现。无论它确切用于什么,我怀疑你不应该从Dictionary继承,甚至不应该实现IDictionary。我认为你应该只编写一个常规类来持有(私有)字典以管理其状态,并具有一些添加、删除和获取方法。 - Stefan Steinegger
3个回答

29
你离正确答案很近了,只需要从构造函数中移除类型参数即可。
class Foo<TKey,TValue> : Dictionary<TKey, TValue>
{   
    Foo():base(){}
    Foo(int capacity):base(capacity){}
}

要重写一个方法,您可以使用override关键字。


2
不是在构造函数中,它们已经在类型内部了,因此它们已经“拥有”类型参数。 - Jon Skeet
不需要在每个方法中重新定义,TKey和TValue现在作为类的一部分被定义。 - Jake Pearson
2
在C#中,public必须明确定义,否则所有内容都默认为private。 - Jake Pearson
1
不需要显式声明时默认为私有访问:类、结构体和枚举默认为internal,而方法、属性和字段默认为private。 - Polyfun
6
如果从Dictionary继承而来的方法都不是虚拟的,那么继承它有什么意义? - cowlinator
显示剩余4条评论

19

并非直接回答你的问题,只是提供一些建议。我不会继承字典,而是实现IDictionary<T,K>并聚合一个字典。这很可能是更好的解决方案:

class Foo<TKey,TValue> : IDictionary<TKey, TValue>
{   

    private Dictionary<TKey, TValue> myDict;

    // ...
}

如果我只想使用名称为Foo的字典,你有什么建议? - Pratik Deoghare
你为什么要这样做?一种类似于C语言的typedef吗? - Stefan Steinegger
这是一个装饰器模式(http://en.wikipedia.org/wiki/Decorator_pattern)。可能的缺点是:您需要手动实现从您的类到成员字典的每个连接。 - The Chairman
@Mao:没错,你需要实现每个方法,但你也可能会发现拥有完全的控制权很实用。 - Stefan Steinegger
1
@TheChairman 如果你在使用ReSharper的话,有一个非常方便的上下文操作可以将所有的IDictionary成员委托给myDict字段(当修复“缺少成员”错误时)。你也可以按下alt+ins并选择“委托成员...”来插入它们。这样可以节省很多工作! - MarioDS
直接从字典继承有什么不好的解决方案意义? - t3chb0t

10
如果你只是想要相同类型但具有不同名称,你可以使用using别名来缩短它:
using Foo = System.Collections.Generic.Dictionary<string, string>;

然后

Foo f = new Foo();

这是正确的并且可行的。但不幸的是,Visual Studio对别名提供的支持不够好。在代码中右键单击“Foo”并选择“转到定义”将会带您到泛型Dictionary<TKey, TValue>的定义处。而“转到声明”似乎明显有问题。唉。 - Alex Fainshtein

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接