简体   繁体   English

修改字典中的添加:重新实现IDictionary vs继承自Dictionary

[英]Modifying Add in Dictionary: reimplement IDictionary vs inheriting from Dictionary

So let's say that I need to redefine Add in my Dictionary<string, string> . 所以我要说我需要在我的Dictionary<string, string>重新定义Add

Solution A: 解决方案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);
    }
}

Solution B: 解决方案B:

public class InheritedDict : Dictionary<string, string>
{
    public override void Add(string key, string value)
    {
        base.Add(key, value);
    }
}

Another StackOverflow user was telling me (in another thread's comments section) that solution A is the right one. 另一个StackOverflow用户告诉我(在另一个线程的评论部分中)解决方案A是正确的。 Which is the contrary of what I expected. 这与我的预期相反。

Apparently it is because "Add isn't a virtual method". 显然这是因为“添加不是虚拟方法”。 He was pointing me to the documentation: https://msdn.microsoft.com/en-us/library/k7z0zy8k(v=vs.110).aspx 他指着我的文档: https//msdn.microsoft.com/en-us/library/k7z0zy8k(v=vs.110).aspx

I confess that I still don't get it. 我承认我仍然没有得到它。

Edit : so the question is: why would solution B be considered bad code? 编辑 :所以问题是:为什么解决方案B会被视为坏代码? (sorry, @Backs's answer made sense when I wrongly asked "why would solution A be considered bad code?") (对不起,当我错误地问“为什么解决方案A被认为是坏代码?”时,@ Backs的回答是有道理的。)

When you shadow a method, if the client code calls the method with instance typed as base class, then your method will not be called. 当您遮蔽方法时,如果客户端代码调用实例类型为基类的方法,则不会调用您的方法。 It will call base class method. 它将调用基类方法。

This is the main reason why you're suggested to use method1. 这是建议您使用method1的主要原因。

For example: 例如:

Dictionary<string, string> dic = new InheritedDict();
dic.Add("key","value");//Will not call your method.

If the Add method was declared virtual(it isn't), you could have overridden the Add method. 如果Add方法被声明为虚拟(它不是),则可以覆盖Add方法。 In that case it will call the derived class method as you expect. 在这种情况下,它将按预期调用派生类方法。

Short - No reason :) I don't see problems. 简短 - 没理由:)我没有看到问题。 You have your own implementation of IDictionary. 您有自己的IDictionary实现。 It's ok. 没关系。

Yet another possibility is an extension method : 另一种可能性是扩展方法

  public static DictionaryExtensions {
    public static void MyAdd(this Dictionary<string, string> dictionary, String key, String value) {
      ...
    }
  } 

So you can use existing Dictionary<String, String> implementation (Microsoft) with extended functionality: 因此,您可以使用具有扩展功能的现有Dictionary<String, String>实现(Microsoft):

  Dictionary<string, string> dict = new Dictionary<string, string>();
  ...
  dict.MyAdd("myKey", "SomeValue");

You can think of it as each implemented interface has its own virtual method table . 你可以想到它,因为每个实现的接口都有自己的虚方法表

Still Dictionary.Add is not virtual you can't call inheritor's implementation: 仍然是Dictionary.Add不是虚拟的你不能调用inheritor的实现:

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

But: 但:

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

Second way is a difficult, right? 第二种方式是困难的,对吧​​?

So it's better implement entire interface IDictionary instead of overriding the single method of Dictionary . 因此,最好实现整个接口IDictionary而不是覆盖Dictionary的单个方法。 Therefore, although the solution A is a little bit verbose, but it's absolutely correct. 因此,虽然解决方案A有点冗长,但它绝对正确。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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