【问题标题】:Why can't I call methods within a class that explicitly implements an interface?为什么我不能在显式实现接口的类中调用方法?
【发布时间】:2010-03-26 01:54:49
【问题描述】:

故事是这样的。我创建了一个界面,IVehicle。我在课堂上明确实现了接口Vehicle.cs

这是我的界面:

Interface IVehicle
{
        int getWheel();
}

这是我的课:

class Vehicle: IVehicle
{

     public int IVehicle.getWheel()
     {
         return wheel;
     }

     public void printWheel()
     {
         Console.WriteLine(getWheel());
     }
}

请注意,getWheel() 已明确实现。现在,当我尝试在 Vehicle 类中调用该方法时,我收到一条错误消息,指出当前上下文中不存在 getWheel()。有人可以帮我理解我做错了什么吗?

【问题讨论】:

  • 作为一个java人,我想知道为什么会存在这个令人费解的事情?为什么会有人希望上述存在,它有什么好处?
  • 在显式实现的成员上指定可见性修饰符是语法错误。一旦您的对象被转换为您的接口类型,该成员始终可以访问。
  • @mP 如果您使用一个公共成员实现多个接口,这允许您为每个接口提供不同的定义。它还增加了清理智能感知,因为除非您强制转换为正确的接口,否则显式成员不可见或不可用。
  • 对我来说,它还增加了代码的可读性。想象一个大班,在某个地方你有一个putlic int Clean(int n) {...}。这是一个接口方法还是不是?你可以重命名它,删除n,还是不能?使用显式实现,您无需进行调查 - 您会立即看到这一点。

标签: c# interface explicit


【解决方案1】:

当显式实现接口时,首先必须将对象强制转换为接口,然后才能调用方法。换句话说,该方法仅在作为接口类型而不是作为具体类型在对象上调用该方法时才可用。

class Vehicle: IVehicle {

     public int IVehicle.getWheel()
     {
         return wheel;
     }

     public void printWheel()
     {
         Console.WriteLine( ((IVehicle)this).getWheel() );
     }
}

有关详细信息,请参阅 MSDN 上的 reference。这是相关的sn-p:

在方法调用、属性访问或索引器访问中,无法通过其完全限定名称访问显式接口成员实现。显式接口成员实现只能通过接口实例访问,并且在这种情况下仅通过其成员名称引用。

对于它的价值——这可能不是对显式接口实现的特别好的使用。通常,当您的类具有用于典型操作的完整接口但也实现了可能取代其中一些操作的接口时,您希望使用显式实现。典型示例是实现IDisposableFile 类。它将有一个Close() 方法,但需要实现Dispose()。当视为File 时,您将使用Open/Close。但是,当在 using 语句中打开时,它会将其视为 IDisposable 并调用 Dispose。在这种情况下,Dispose 只需调用Close。您不一定希望将Dispose 公开为File 实现的一部分,因为Close 提供了相同的行为。

【讨论】:

  • 谢谢。我这样做只是为了向自己证明我可以做到。到目前为止,我正在使用的书没有给出任何理由表明需要显式实现接口。
  • 另一个常见的例子是在 winforms 应用程序生成的.Designer 文件中。每个控件都在一对.BeginInit().EndInit() 方法之间进行初始化,但这些调用都是在 将控件转换为ISupportInitialize 之后进行的。
【解决方案2】:

根据MSDN

可以实现 显式接口成员——创建一个 只被调用的类成员 通过界面,并且是具体的 到那个界面。

而在C# language specifications

无法访问 显式接口成员 通过其充分实施 方法调用中的限定名称, 属性访问或索引器访问。一个 显式接口成员 实现只能访问 通过一个接口实例,并且是 在这种情况下,仅由其引用 会员名。

要访问此成员,您可以先将类强制转换为接口,然后再访问它。

【讨论】:

    【解决方案3】:

    为了避免对你的类进行大量无聊的强制转换,你可以创建一个指针作为接口类型

    public class Foo : IBar
    {
        readonly IBar bar;
        public Foo()
        {
           bar = this;
        }
    }
    

    然后使用bar.呼叫成员

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-10-04
      • 2010-11-18
      • 1970-01-01
      • 1970-01-01
      • 2011-02-25
      • 2011-04-26
      • 2015-02-12
      相关资源
      最近更新 更多