13

次の例を見てください。

public interface IFoo
{
    IFoo Bar();
}

public class Foo : IFoo
{
    public Foo Bar()
    {
        //...
    }

    IFoo IFoo.Bar() { return Bar(); } //Why is this necessary?
}

キャストなしに変換しても、暗黙的な実装がIFoo Bar()必要なのはなぜですか?FooIFoo

4

5 に答える 5

5

この場合に必要なのは、C# がインターフェイスの戻り値の型の共分散をサポートしていないためです。

public Foo Bar()
{
    //...
}

IFooメソッドの戻り値の型が異なるため、インターフェースを満たしていませんBar

Bar()インターフェイスも実装する必要があるため、クラスでメソッドが既に定義されているため、明示的に実装するしかありません。

于 2012-12-19T19:49:48.250 に答える
5

Microsoft はこの件について詳細な記事を書いていますが、同じメソッドを持つ複数のインターフェイス/クラスの実装に要約されます。Implicitは、そのコンテキストでは機能しなくなりました。

class Test 
{
    static void Main()
    {
        SampleClass sc = new SampleClass();
        IControl ctrl = (IControl)sc;
        ISurface srfc = (ISurface)sc;

        // The following lines all call the same method.
        sc.Paint();
        ctrl.Paint();
        srfc.Paint();
    }
}


interface IControl
{
    void Paint();
}
interface ISurface
{
    void Paint();
}
class SampleClass : IControl, ISurface
{
    // Both ISurface.Paint and IControl.Paint call this method.  
    public void Paint()
    {
        Console.WriteLine("Paint method in SampleClass");
    }
}

// Output: 
// Paint method in SampleClass 
// Paint method in SampleClass 
// Paint method in SampleClass

明示的なアプローチを取るとしたら、これになります。

public class SampleClass : IControl, ISurface
{
    void IControl.Paint()
    {
        System.Console.WriteLine("IControl.Paint");
    }
    void ISurface.Paint()
    {
        System.Console.WriteLine("ISurface.Paint");
    }
}

要するに、実装された型が衝突したときに一意性を提供することです。あなたの例では、Foo です IFoo

于 2012-12-19T19:47:08.840 に答える
4

次のように解決できます(少し醜いですが、強い型付けを処理します):

public interface IFoo<T> where T : IFoo<T>
{
    T Bar();
}

public class Foo : IFoo<Foo>
{
    public Foo Bar()
    {
        //...
    }
}
于 2012-12-19T19:47:34.520 に答える
3

インターフェイスを実装するメソッドが、同じシグネチャを持つメソッドの別のバージョンと同じように動作することを常に望んでいるとは限らないためです。

また、クラスでインターフェイスのメソッドを実装したいが、そのメソッドはクラス自体のインスタンスからアクセスできないようにすることもできます。

于 2012-12-19T19:43:24.553 に答える
0

暗黙の実装を公開ではなく保護することをお勧めします。

public class Foo : IFoo
{
    **protected virtual** Foo Bar()
    {
        //...
    }

    IFoo IFoo.Bar() { return Bar(); } 
}

このスレッドで明示的な実装を使用する理由/時期については、かなり広範な回答があります。

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

明示的な実装を使用する正当な理由は、Foo クラスを使用するときに依存性注入を簡単に使用して、より疎結合を実現できることです。

于 2012-12-19T19:52:10.827 に答える