web-dev-qa-db-ja.com

インターフェイスを明示的に実装するクラス内のメソッドを呼び出せないのはなぜですか?

これが物語です。インターフェースIVehicleを作成しました。クラス_Vehicle.cs_にインターフェイスを明示的に実装しました。

これが私のインターフェースです:

_Interface IVehicle
{
        int getWheel();
}
_

これが私のクラスです:

_class Vehicle: IVehicle
{

     public int IVehicle.getWheel()
     {
         return wheel;
     }

     public void printWheel()
     {
         Console.WriteLine(getWheel());
     }
}
_

getWheel()が明示的に実装されていることに注意してください。ここで、Vehicleクラス内でそのメソッドをcallしようとすると、getWheel()が現在のコンテキストに存在しないことを示すエラーが表示されます。誰かが私が間違っていることを理解するのを手伝ってくれますか?

38
tyrone302

インターフェイスを明示的に実装する場合は、最初にオブジェクトをインターフェイスにキャストしてから、メソッドを呼び出す必要があります。つまり、このメソッドは、具体的な型ではなく、インターフェイス型としてオブジェクトでメソッドが呼び出された場合にのみ使用できます。

_class Vehicle: IVehicle {

     public int IVehicle.getWheel()
     {
         return wheel;
     }

     public void printWheel()
     {
         Console.WriteLine( ((IVehicle)this).getWheel() );
     }
}
_

詳細については、MSDNのこの 参照 を参照してください。関連するスニペットは次のとおりです。

メソッド呼び出し、プロパティアクセス、またはインデクサーアクセスで、完全修飾名を使用して明示的なインターフェイスメンバーの実装にアクセスすることはできません。明示的なインターフェイスメンバーの実装には、インターフェイスインスタンスを介してのみアクセスでき、その場合は、そのメンバー名によってのみ参照されます。

価値があるのは、これはおそらく明示的なインターフェース実装の特に良い使用法ではないでしょう。通常、一般的な操作のための完全なインターフェースを備えているが、それらの操作の一部に取って代わる可能性のあるインターフェースも実装しているクラスがある場合は、明示的な実装を使用する必要があります。正規の例は、Fileを実装するIDisposableクラスです。 Close()メソッドがありますが、Dispose()を実装する必要があります。 Fileとして扱う場合は、_Open/Close_を使用します。ただし、usingステートメントで開くと、それはIDisposableとして扱われ、Disposeを呼び出します。この場合、Disposeは単にCloseを呼び出します。同じ動作がDisposeから利用できるため、File実装の一部としてCloseを公開する必要は必ずしもありません。

44
tvanfosson

[〜#〜] msdn [〜#〜] によると:

インターフェイスメンバーを明示的に実装することは可能です— インターフェイスを介してのみ呼び出されるクラスメンバー、およびそのインターフェイスに固有です。

そして C#言語仕様

メソッド呼び出し、プロパティアクセス、またはインデクサーアクセスで、完全修飾名を使用して明示的なインターフェイスメンバーの実装にアクセスすることはできません。明示的なインターフェイスメンバーの実装には、インターフェイスインスタンスを介してのみアクセスでき、その場合は、そのメンバー名によってのみ参照されます。

このメンバーにアクセスするには、最初にクラスをインターフェースにキャストしてから、それにアクセスします。

13

クラスでの退屈なキャストを避けるために、インターフェイスタイプとしてポインタを作成できます。

public class Foo : IBar
{
    readonly IBar bar;
    public Foo()
    {
       bar = this;
    }
}

そして、bar.を使用してメンバーに電話をかけます

3
Davi Fiamenghi