16

今日、私は1つのC#クラスが暗黙的および明示的な方法の両方で1つのインターフェイスを継承できることに気付きました。これは私を驚かせます。C#がこのように機能する場合、1つのインスタンスは、異なる方法で参照されたときに異なる動作をする可能性があります。

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#の設計は、動作の不整合を引き起こすと思います。おそらく、1つのC#クラスが暗黙的または明示的な方法で1つのインターフェイスから継承できることが必須ですが、両方を継承することはできません。

C#がそのように設計されている理由はありますか?

4

5 に答える 5

13

インターフェイスを実装するすべてのクラスには、そのクラスのメンバーとインターフェイスのメンバー間のマッピングがあります。クラスがインターフェイスメンバーを明示的に実装する場合、明示的な実装は常にインターフェイスにマップされます。明示的な実装がない場合は、暗黙的な実装が想定され、その実装がインターフェイスにマップされます。

クラスがインターフェイスと同じメンバー名と関連するタイプを持っているが、インターフェイス対応するメンバーも明示的に実装している場合、クラスの「暗黙的な」実装は、インターフェイスの実装とはまったく見なされません(明示的な実装が呼び出されない限り)それ)。

クラスが同じメンバー名/タイプの複数のインターフェースを実装するそれぞれの場合の異なる意味に加えて、1つのインターフェースしかない場合でも、クラス自体は、唯一のインターフェースと同じメンバー/タイプを持つ可能性のある暗黙のインターフェースを持っていると見なされますしかし、それでも何か違うことを意味します。

于 2008-10-31T10:28:49.693 に答える
11

あなたの例は、暗黙的および明示的に IFoo を実装していません。IFoo.DoSometing() を明示的に実装するだけです。クラスに DoSomething() という新しいメソッドがあります。名前とパラメーターが同じであることを除いて、IFoo.DoSomething とは何の関係もありません。

于 2008-10-31T10:33:37.937 に答える
7

これにより、衝突が発生した場合の柔軟性が高まります。特に、とを見てくださいIEnumeratorIEnumerator<T>どちらにもCurrentプロパティがありますが、タイプは異なります。両方を実装するには、明示的なインターフェイス実装を使用する必要があります(一般的な形式は非一般的な形式を拡張します)。

于 2008-10-31T10:30:33.310 に答える
2

多重継承:異なる目的のために同じメソッドを定義する2つのインターフェースから派生した場合はどうなりますか?

  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();
    }
  }
于 2008-10-31T10:29:48.273 に答える
0

Guys, Thanks for your answers.

It turns out that "C# class can inherits one interface in both implicit and explicit way at same time" is actually a illusion. Actually, one class can inherit one interface for one time.

In the original question, the "DoSomething" method seems "implicitly implement" interface IFoo (the method is actually generated by VS2008), but it is actually NOT. With explicit implementation of interface IFoo, the "DoSomething" method turns to be just normal method which has nothing to do with IFoo except with same signature.

I still believe it is a tricky design of C#, and it is easy to use it mistakenly. Say, I have some code like this

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

Now, I want to refactor it to below code. It seems perfectly OK, but the execution result is different.

        Action<IFoo> func = foo => foo.DoSomething();
        func(f);
于 2008-10-31T11:19:34.927 に答える