所以,我要说我需要在Add
中重新定义Dictionary<string, string>
。
解决方案A:
public class ImplementedDict : IDictionary<string, string>
{
private readonly Dictionary<string, string> _data = new Dictionary<string, string>();
public void Add(string key, string value)
{
_data.Add(key, value);
}
}
解决方案B:
public class InheritedDict : Dictionary<string, string>
{
public override void Add(string key, string value)
{
base.Add(key, value);
}
}
另一个StackOverflow用户在解释我(在另一个帖子的评论中)解决方案A是正确的。这与我的想法相反。
显然这是因为“添加不是虚拟方法”。他指着我的文档(https://msdn.microsoft.com/en-us/library/k7z0zy8k(v=vs.110).aspx)。
我承认我仍然没有得到它。
编辑:所以问题是:为什么解决方案A会被视为错误代码? (对不起,当我错误地问“为什么解决方案 A 被视为不良代码?”时,@ Backs的答案才有意义。)
答案 0 :(得分:4)
当您遮蔽方法时,如果客户端代码调用实例类型为基类的方法,则不会调用您的方法。它将调用基类方法。
这是您建议使用method1的主要原因。
例如:
Dictionary<string, string> dic = new InheritedDict();
dic.Add("key","value");//Will not call your method.
如果Add
方法被声明为虚拟(它不是),则可以覆盖Add
方法。在这种情况下,它将按预期调用派生类方法。
答案 1 :(得分:2)
短 - 没理由:) 我没有看到问题。您有自己的IDictionary实现。没关系。
答案 2 :(得分:2)
另一种可能性是扩展方法:
public static DictionaryExtensions {
public static void MyAdd(this Dictionary<string, string> dictionary, String key, String value) {
...
}
}
因此,您可以使用具有扩展功能的现有Dictionary<String, String>
实现(Microsoft):
Dictionary<string, string> dict = new Dictionary<string, string>();
...
dict.MyAdd("myKey", "SomeValue");
答案 3 :(得分:2)
您可以将其视为每个实现的接口都有自己的虚拟方法表。
仍然Dictionary.Add
不是虚拟,您无法调用继承人的实施:
Dictionary<string, string> d = new InheritedDict<string, string>(); // Ok, you can do it
d.Add("foo", "bar"); // Wrong! You can, but Dictionary.Add will be called
可是:
public class InheritedDict : Dictionary<string, string>
{
void IDictionary<string, string>.Add(string key, string value)
{
base.Add(key, value);
}
}
Dictionary<string, string> d = new InheritedDict<string, string>();
var d2 = d as IDictionary<string, string>;
d2.Add("foo", "bar"); // Ok
第二种方式是困难的,对吧?
因此,它可以更好地实现整个接口IDictionary
,而不是覆盖Dictionary
的单个方法。因此,尽管解决方案A有点冗长,但它绝对正确。