web-dev-qa-db-ja.com

C#8のデフォルトのインターフェース実装では多重継承が可能ですか

https://blogs.msdn.Microsoft.com/dotnet/2018/11/12/building-c-8-0/ によると、C#8に含まれる新機能の1つがデフォルトですインターフェースの実装。この新機能は、暗黙的に多重継承も許可しますか?そうでない場合、私が以下を試した場合、正確にはどうなりますか:

public interface A { int Foo() => 1; }
public interface B { int Foo() => 2; }
public class C : A, B { }
24
Roy Stoof

この答えを促した彼/彼女の素晴らしいコメントのために@CodeCasterへのクレジット。

プロポーザル の状態:

クラスはそのインターフェースからメンバーを継承しないことに注意してください。この機能によって変更されることはありません。

したがって、それが妥当であるように思われます(出荷されるまで100%の確実性で確認することは不可能ですが)。

_public interface A { int Foo() => return 1; }
public interface B { int Foo() => return 2; }
public class C : A, B { }
_

正常に動作します。

提案が示すように:

_new C().M(); // error: class 'C' does not contain a member 'M'
_

次に、あなたのバージョンを仮定することができます:

_new C().Foo();
_

また、コンパイルされません。

提案は示しています:

_IA i = new C();
i.M();
_

有効であり、次のものと同等です。

_A i = new C();
i.Foo();
_

iはタイプAとして宣言されているため、ABに変更されても同じことが機能しないと想定する理由はありません。について話す。

この機能の要点は、インターフェースを安全な方法で拡張できるようにすることです( このビデオ を参照)。これをonlyが1つのインターフェースを実装した場合に機能する場合、それは機能の目的に反するようです。そして、機能が大体明示的なインターフェース実装に似た方法で実装されているように見えるので(C.Foo()を直接呼び出すことができないのはこのためです)、 合理的に複数のインターフェースの実装を可能にする可能性が最も高いと想定できます。

10
mjwills

あなたの質問は、あなたがリンクしたブログの投稿でMads Torgersenによって回答されています:

実際、インターフェースはまだ抽象クラスからかなり離れています。クラスはインターフェースからメンバーを継承しないので、クラスがインターフェースによって実装されたメンバーMを残した場合、クラスにはメンバーMがありません!今日の明示的な実装のようです。そのようなメンバーを取得するには、インターフェースに変換する必要があります。

だからあなたの例で:

public interface A { int Foo() => 1; }
public interface B { int Foo() => 2; }
public class C : A, B { }

あなたはこれを行うことができません:

var something = new C();
var x = something.Foo(); /* does not compile */

次のことができます。

var something = new C();
var x = ((A)something).Foo(); /* calls the implementation provided by A */
var y = ((B)something).Foo(); /* calls the implementation provided by B */
17
user247702