【问题标题】:C# call interface method within classC#调用类内的接口方法
【发布时间】:2011-02-17 20:36:53
【问题描述】:
interface ILol
{
   void LOL();
}

class Rofl : ILol
{
   void ILol.LOL()
   {
      GlobalLOLHandler.RaiseROFLCOPTER(this);
   }
   public Rofl()
   {
      //Is there shorter way of writing this or i is there "other" problem with implementation??
      (this as ILol).LOL();
   }
}

【问题讨论】:

  • 尽量避免从构造函数调用“虚拟”函数!您最终可能会调用一个访问未完全构造的对象的实现。

标签: c# class interface call


【解决方案1】:

您已经实现了接口explicitly,通常您不需要这样做。相反,只需隐式实现它并像调用任何其他方法一样调用它:

class Rofl : ILol
{
    public void LOL() { ... }

    public Rofl()
    {
        LOL();
    }
}

(请注意,您的实现也需要公开。)

【讨论】:

  • 您意识到您的代码示例仍然显式地实现它,对吧? :)
  • 隐式和显式实现有什么区别?如果我不添加 ILol。在 LOL 之前,编译器会抱怨没有 ILol.LOL 的暗示。
  • 只有在对象被转换为接口类型时才能调用显式接口。这有各种不明显的优点,但否则你应该避免它。至于为什么你的代码不起作用,我只能猜测:实现你的接口的方法是否可以公开访问?
  • 澄清一下:ladenedge 在上面的评论中所说的是,当他拿走 ILol. 时,OP 需要在他的声明前添加 public
【解决方案2】:

如果您明确实现接口,则不会。如果您通过从实现的方法中删除接口名称使其隐含,它将按您的意愿工作。

void LOL()
{
    GlobalLOLHandler.RaiseROFLCOPTER(this);
}
public Rofl()
{
    LOL();
}

【讨论】:

    【解决方案3】:

    您根本不需要投射。由于ROFL 实现了ILOL,您可以简单地调用this.LOL() 甚至只是LOL();

    【讨论】:

    • -1 错误。 ROFL 显式实现了ILOL,并且在没有访问ILOL 的实例(this casted)的情况下无法访问ILOL 成员。
    【解决方案4】:

    您可能希望将演员阵容从 (this as ILol) 更改为 ((ILol)this)。 as cast 允许返回 null,这可能会在以后导致令人困惑的错误,并且编译器必须对其进行测试。

    【讨论】:

    • 再来一次?与非as 相比,as 演员表有什么问题?
    • 在检查 null 之前使用从as 返回的对象是一种不好的做法。上面的代码在编写时不会出现任何问题,但在重构期间不会有弹性。
    • as cast可以返回null,所以编译器在调用该方法之前需要先测试null,这样才能产生空引用异常。常规转换永远不会返回 null,因此编译器可以省略对 null 的测试。
    • 上述讨论可能会使最近学会使用as 的人感到困惑,因此他们可以处理无法将对象强制转换为目标类型的情况。规则是:如果您不能 100% 确定转换始终有效,请使用 as,然后测试结果是否为 null。如果它不可能失败[这里,我们知道thisILol,因为它被定义为],那么直接转换,(ILol)
    【解决方案5】:

    不要使用as,只需投射:

    ((ILol)this).LOL();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-01-15
      • 1970-01-01
      • 1970-01-01
      • 2017-11-29
      • 1970-01-01
      • 2020-12-24
      • 2011-02-12
      • 1970-01-01
      相关资源
      最近更新 更多