20

私は C++ から C# を学んでいて、壁にぶつかりました。

抽象クラス AbstractWidget、インターフェイス IDoesCoolThings、および RealWidget と呼ばれる AbstractWidget から派生したクラスがあります。

public interface IDoesCoolThings
{
    void DoCool();
}

public abstract class AbstractWidget : IDoesCoolThings
{
    void IDoesCoolThings.DoCool()
    {
        Console.Write("I did something cool.");
    }
}

public class RealWidget : AbstractWidget
{

}

RealWidget オブジェクトをインスタンス化し、それに対して DoCool() を呼び出すと、コンパイラから次のエラーが表示されます。

「RealWidget」には「DoCool」の定義が含まれていません

RealWidget オブジェクトを IDoesCoolThings にキャストすると、呼び出しが機能しますが、それは不要なようで、ポリモーフィズムも失われます (RealWidget.DoCool() を定義しても、AbstractWidget.DoCool() は常に呼び出されます)。

解決策は簡単だと思いますが、さまざまなことを試しましたが、一生これを理解することはできません.

4

4 に答える 4

42

明示的なインターフェイスの実装(EII)を使用したため、問題が発生しています。メンバーが明示的に実装されている場合、クラス インスタンスを介してアクセスすることはできません。インターフェイスのインスタンスを介してのみアクセスできます。DoCool()あなたの例では、インスタンスを にキャストしない限り呼び出すことができないのはそのためですIDoesCoolThings

解決策はDoCool()、明示的なインターフェイスの実装を公開して削除することです。

public abstract class AbstractWidget : IDoesCoolThings
{
    public void DoCool()      // DoCool() is part of the abstract class implementation.
    {
        Console.Write("I did something cool.");
    }
}

// ...

var rw = new RealWidget();
rw.DoCool();                  // Works!

通常、EII は次の 2 つの場合に使用します。

  • 2 つのインターフェイスを実装する必要があるクラスがあり、それぞれのインターフェイスには、他のインターフェイスの別のメンバーと同じ名前/署名を持つメンバーが含まれています。
  • クラスの実装の詳細に依存するのではなく、クラスによって実装されているインターフェイスにクライアントを依存させる必要があります。(これは良い習慣と考えられています。)
于 2009-03-26T02:03:33.717 に答える
8

宣言を次のように変更します。

public abstract class AbstractWidget : IDoesCoolThings 
{
    public void DoCool()
    { 
        Console.Write("I did something cool."); 
    }
}
于 2009-03-26T02:04:18.957 に答える
7

インターフェイスを実装する方法は、明示的に実装する void IDoesCoolThings.DoCool() であり、暗黙的に実装するインターフェイスを選択した場合です。

public abstract class AbstractWidget : IDoesCoolThings
{
    public void DoCool()
    {
        Console.Write("I did something cool.");
    }
}

それはうまくいくでしょう。

これを読む :

C# インターフェイス。暗黙的な実装と明示的な実装

于 2009-03-26T02:04:38.833 に答える
1

このようにする必要があります:

public interface IDoesCoolThings 
{
   void DoCool();
}

public abstract class AbstractWidget 
{
   public void DoCool()
   {
      Console.WriteLine("I did something cool.");
   }
}

public class Widget : AbstractWidget, IDoesCoolThings 
{
}

使用法:

var widget = new Widget();
widget.DoCool();
于 2013-01-30T07:38:24.580 に答える