今天我碰巧发现一个C#类可以以隐式和显式方式继承一个接口。这让我感到惊讶。如果C#以这种方式工作,那么当以不同方式引用时,一个实例的行为会有所不同。

interface IFoo
{
    void DoSomething();
}

class Foo : IFoo
{
    #region IFoo Members
    public void DoSomething()
    {
        Console.WriteLine("do something implicitly");
    }
    #endregion

    #region IFoo Members
    void IFoo.DoSomething()
    {
        Console.WriteLine("do something explicitly");
    }
    #endregion
}


        Foo f = new Foo();
        f.DoSomething();

        ((IFoo)f).DoSomething();

以上代码运行并输出

do something implicitly
do something explicitly

我认为这种C#设计会使行为不一致。也许强制一个C#类可以以隐式或expliict方式从一个接口继承,但不能同时从两个接口继承。

有没有理由为什么C#以这种方式设计?

有帮助吗?

解决方案

您的示例隐式和显式地实现IFoo。您只能显式实现IFoo.DoSometing()。您的类上有一个名为DoSomething()的新方法。它与IFoo.DoSomething无关,只是它具有相同的名称和参数。

其他提示

实现接口的每个类在该类的成员和接口的成员之间都有映射。如果类显式实现了接口成员,那么显式实现将始终映射到接口。如果没有显式实现,则需要隐式实现,并且该实现将映射到接口。

当一个类具有相同的成员名称和关联类型作为接口时,它还显式实现了接口的相应成员,然后是类的<!> quot; implicit <!> quot;实现被认为是接口的所有的实现(除非显式实现调用它)。

除了在每种情况下类具有相同成员名称/类型的多个接口的不同含义之外,即使只有一个接口,类本身也被认为具有可能的隐式接口与唯一的界面具有相同的成员/类型,但仍然意味着不同的东西。

这使得它在发生碰撞时更加灵活。请特别注意 IEnumerator IEnumerator<T> - 它们都有Current属性,但属于不同类型。你使用显式接口实现来实现它们(并且泛型形式扩展了非泛型形式)。

多重继承: 如果从两个为不同目的定义相同方法的接口派生,该怎么办?

  interface IMoveable
  {
    public void Act();
  }

  interface IRollable
  {
    public void Act();
  }

  class Thing : IMoveable, IRollable
  {
    //TODO Roll/Move code here

    void IRollable.Act()
    {
      Roll();
    }

    void IMoveable.Act()
    {
      Move();
    }
  }

伙计们,谢谢你的回答。

事实证明<!> C#类可以同时以隐式和显式两种方式继承一个接口<!>实际上是一种幻觉。实际上,一个类可以一次继承一个接口。

在原始问题中,<!>“DoSomething <!>”;方法似乎<!>“隐式实现<!>”;接口IFoo(该方法实际上是由VS2008生成的),但实际上并非如此。通过显式实现接口IFoo,<!>“DoSomething <!>”;方法变成了正常的方法,除了具有相同的签名外,与IFoo无关。

我仍然认为它是一个棘手的C#设计,很容易误用它。说,我有一些像这样的代码

        Foo f = new Foo();
        f.DoSomething();

现在,我想将它重构为下面的代码。看起来完全没问题,但执行结果不同。

        Action<IFoo> func = foo => foo.DoSomething();
        func(f);
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top