web-dev-qa-db-fra.com

Les implémentations d'interface par défaut C # 8 permettent-elles un héritage multiple

Selon https://blogs.msdn.Microsoft.com/dotnet/2018/11/12/building-c-8-0/ , l'une des nouvelles fonctionnalités à venir en C # 8 est la valeur par défaut mise en place d'interfaces. Cette nouvelle fonctionnalité permettra-t-elle également implicitement l'héritage multiple? Sinon, que se passera-t-il exactement si j'essaye ce qui suit:

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

Nous remercions @CodeCaster pour ses excellents commentaires qui ont motivé cette réponse.

proposition déclare:

Notez qu'une classe n'hérite pas des membres de ses interfaces; qui n'est pas modifié par cette fonctionnalité:

Ainsi, il semble raisonnable (bien qu'il soit impossible de confirmer avec 100% de certitude jusqu'à ce qu'il soit expédié) que:

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

fonctionnera bien.

Tout comme le montre la proposition:

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

alors nous pouvons supposer, votre version:

new C().Foo();

ne compilera pas non plus.

La proposition montre:

IA i = new C();
i.M();

valide, ce qui équivaut à votre:

A i = new C();
i.Foo();

Puisque i est déclaré comme type A, il n'y a aucune raison de supposer que cela ne fonctionnerait pas si A était changé en B - il n'y a pas de collision avec parler de.

L'intérêt de cette fonctionnalité est de permettre l'extension des interfaces en toute sécurité (voir cette vidéo ). Si cela seulement fonctionnait si vous avez implémenté une interface, cela semble contraire à l'objectif de la fonctionnalité. Et étant donné que la fonctionnalité semble être implémentée d'une manière à peu près semblable à une implémentation d'interface explicite (c'est pourquoi nous ne pouvons pas invoquer C.Foo() directement), je pense que nous pouvons = raisonnablement supposons que cela permettra très probablement l'implémentation de plusieurs interfaces.

10
mjwills

Mads Torgersen répond à votre question dans le blog auquel vous avez lié:

En fait, les interfaces sont encore assez loin des classes abstraites. Les classes n'héritent pas des membres des interfaces, donc si une classe quitte un membre M implémenté par l'interface, la classe n'a pas de membre M! C’est comme une implémentation explicite aujourd’hui; vous devez vous convertir à l'interface pour accéder à ces membres.

Donc avec votre exemple:

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

Tu ne peux pas faire ça:

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

Vous pouvez effectuer les opérations suivantes:

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