【问题标题】:How to call the interface method in its own class?如何在自己的类中调用接口方法?
【发布时间】:2011-05-13 18:17:03
【问题描述】:

MySqlConnection 类实现IDatabaseConnection 接口。在update方法中,我想调用connect(),但是找不到这个方法,怎么调用呢?

class MySqlConnection : IDatabaseConnection
{
    void IDatabaseConnection.connect()
    {
        ...
    }

    void IDatabaseConnection.update()
    {         
        connect(); // here
        ...
    }
}

【问题讨论】:

  • IDatabaseConnectionIDatabase有什么关系??
  • @abatishchev:我认为应该只是IDatabaseConnection
  • 哦,谢谢。我现在改了

标签: c# interface methods


【解决方案1】:

这称为显式接口实现。但是如果你这样写你的类,它可以正常工作:

class MySqlConnection : IDatabase
{
    public void connect()
    {
        ...
    }

    public void update()
    {         
        connect(); // here
        ...
    }
}

请注意,这些方法是作为公共方法实现的。

显式实现使它们在任何地方都无法访问,即使在类本身内部也是如此。这就是为什么在声明它们时不能使用private 关键字。但是,它们仍然可以通过界面“公开”访问。如果出于某种充分的理由您真的想使用显式实现,您可以强制转换为接口并从那里调用:

((IDatabase)this).connect();

【讨论】:

    【解决方案2】:

    你可以使用:

    (this as IDatabase).connect();
    

    原因是你显式地实现了这个接口,所以你只能在转换后调用这些方法。为什么要显式实现它并使这些方法private?我认为连接类具有publicconnectupdate 方法更为常见。

    【讨论】:

    • 这不是一个好方法;这里最好使用明确的演员表。 as 应该在强制转换可能失败时使用,并且通常跟在 null-test 之后。
    • @Ani:好点,但在这里不会有什么不同,因为编译器不会关心演员表。
    • @Martinho Fernandes:这是关于可读性的;作为代码的读者,我会误以为这个演员可能会失败;并且这里可能存在空引用问题。静态代码分析工具也是如此。
    • @Ani:可读性可能是一个因素。我个人不在乎,但如果其他人可能会发现问题,那么定期演员会更好。但是智能代码分析工具知道,因为类实现了接口并且this 永远不会为空,所以它永远不会失败。例如,R# 就足够聪明了。
    【解决方案3】:

    这里似乎有几个问题——您的 MySqlConnection 没有实现 IDatabase 接口,但您在该接口中明确实现了一个方法?

    这可能会有所帮助——我可能误解了您想要实现的目标。

    http://msdn.microsoft.com/en-us/library/aa288461(VS.71).aspx

    【讨论】:

      【解决方案4】:

      显式接口实现:

      class MySqlConnection : IDatabaseConnection
      {
          void IDatabaseConnection.connect()
          {
              //
          }
      
          void IDatabaseConnection.update()
          {
              (this as IDatabaseConnection).connect();
          }
      }
      

      更好 - 隐式接口实现:

      class MySqlConnection : IDatabaseConnection
      {
          public void connect()
          {
              //
          }
      
          public void update()
          {
              connect();
          }
      }
      

      【讨论】:

      • 为什么说隐式实现更好?我通常会同意,但也许 OP 有充分的理由使用显式实现......
      • +1 同意隐式实现在大多数情况下更合理。
      • @Thomas:我认为只有当你继承了具有相同名称的方法的 2 个接口并且它们的实现应该不同时,才应该进行显式实现,例如IFoo:Do()IBar:Do()
      【解决方案5】:

      显然您正在使用显式接口实现,除了您的语法不正确(您不能在其上指定访问修饰符)。

      要调用该方法,只需将this 转换为IDatabaseConnection

      void IDatabase.update(){
      
          ((IDatabase)this).connect();
       ...
      }
      

      【讨论】:

      • +1。当然,另一种选择是隐式实现接口,除非这是不可取的。
      • 运算符 as 的工作速度(稍微)比 cast 快,不是吗?
      • @abatishchev:在as 和常规演员之间进行选择的原因不是性能。这是他们的行为。 as 将在失败时生成 null,而常规转换将引发异常。
      • @Martinho: (null).connect(); 也会抛出异常:)
      • @abatishchev:一个毫无意义且无益的例外。问题是,如果演员有时会失败,请使用as 并检查是否为空。如果施法不可能失败,请使用常规施法。如果它不能失败,但它确实失败了,那么就崩溃了,这就是例外,而不是控制流。捕获 NullReferenceException 或 InvalidCastException 是错误的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-30
      • 1970-01-01
      • 2015-11-11
      相关资源
      最近更新 更多