【问题标题】:Visual Studio code generated when choosing to explicitly implement interface选择显式实现接口时生成的 Visual Studio 代码
【发布时间】:2010-06-03 09:22:07
【问题描述】:

抱歉标题含糊,但我不确定这叫什么。

假设我将IDisposable 添加到我的班级,Visual Studio 可以为我创建方法存根。但它会创建像这样的存根:

void IDisposable.Dispose()

我不遵循这种语法的作用。为什么要这样而不是public void Dispose()

对于第一种语法,我不知道如何从我的类中(在我的析构函数中)调用 Dispose()。

【问题讨论】:

    标签: visual-studio code-generation methods interface


    【解决方案1】:

    当您显式实现接口成员时,即生成的代码正在执行的操作,您无法通过类实例访问该成员。相反,您必须通过接口的实例调用它。例如:

    class MyClass : IDisposable
    {
      void IDisposable.Dispose()
      {
        // Do Stuff
      }
    
      ~MyClass()
      {
        IDisposable me = (IDisposable)this;
        me.Dispose();
      }
    }
    

    这使您可以使用同名成员实现两个接口,并独立显式调用任一成员。

    interface IExplict1 
    {
      string InterfaceName();
    }
    
    interface IExplict2
    {
      string InterfaceName();
    }
    
    class MyClass : IExplict1, IExplict2 
    {
      string IExplict1.InterfaceName() 
      {
        return "IExplicit1";
      }
    
      string IExplict2.InterfaceName() 
      {
        return "IExplicit2";
      }
    }
    
    public static void Main() 
    {
      MyClass myInstance = new MyClass();
    
      Console.WriteLine( ((IExplcit1)myInstance).InstanceName() ); // outputs "IExplicit1"
    
      IExplicit2 myExplicit2Instance = (IExplicit2)myInstance;
    
      Console.WriteLine( myExplicit2Instance.InstanceName() ); // outputs "IExplicit2"
    }
    

    【讨论】:

      【解决方案2】:

      Visual Studio 为您提供两种选择:

      • 实施
      • 显式实现

      您通常选择第一个(非显式):它会提供您想要的行为。

      如果您从两个不同的接口继承相同的方法,即多重继承(通常不这样做),“显式”选项很有用。

      【讨论】:

        【解决方案3】:

        接口类型的成员始终是公共的。这也要求他们的方法实现也是公开的。例如,这不会编译:

        interface IFoo { void Bar(); }
        
        class Baz : IFoo {
            private void Bar() { }   // CS0737
        }
        

        显式接口实现提供了允许方法私有的语法:

        class Baz : IFoo {
            void IFoo.Bar() { }   // No error
        }
        

        一个典型的用途是隐藏基本接口类型的实现。 IEnumerable 就是一个很好的例子:

        class Baz : IEnumerable<Foo> {
            public IEnumerator<Foo> GetEnumerator() {}
            System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { }
        }
        

        注意通用版本是如何访问的,非通用版本是隐藏的。这既不鼓励使用它,又避免了由于重复方法而导致的编译错误。


        在您的情况下,显式实施 Dispose() 是错误的。您编写 Dispose() 以允许客户端代码调用它,强制它强制转换为 IDisposable 以使调用没有意义。

        此外,从终结器调用 Dispose() 是一种代码异味。标准模式是向您的类添加受保护的 Dispose(bool disposing) 方法。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-04-11
          • 2012-09-16
          • 2016-11-30
          • 1970-01-01
          • 2010-09-06
          • 2021-08-08
          • 1970-01-01
          • 2010-09-20
          相关资源
          最近更新 更多