Standardschnittstellen Methodendefault interface methods

  • [x] vorgeschlagen[x] Proposed
  • [] Prototyp: in Bearbeitung[ ] Prototype: In progress
  • [] Implementierung: keine[ ] Implementation: None
  • [] Spezifikation: in Bearbeitung[ ] Specification: In progress, below

ZusammenfassungSummary

Hinzufügen von Unterstützung für virtuelle Erweiterungs Methoden -Methoden in Schnittstellen mit konkreten Implementierungen.Add support for virtual extension methods - methods in interfaces with concrete implementations. Eine Klasse oder Struktur, die eine solche Schnittstelle implementiert, muss über eine einzige spezifischere Implementierung für die Schnittstellen Methode verfügen, die entweder von der Klasse oder Struktur implementiert wird oder von ihren Basisklassen oder Schnittstellen geerbt wird.A class or struct that implements such an interface is required to have a single most specific implementation for the interface method, either implemented by the class or struct, or inherited from its base classes or interfaces. Mithilfe von virtuellen Erweiterungs Methoden kann ein API-Autor Methoden zu einer Schnittstelle in zukünftigen Versionen hinzufügen, ohne dass die Quell-oder Binärkompatibilität mit vorhandenen Implementierungen dieser Schnittstelle unterbrochen wird.Virtual extension methods enable an API author to add methods to an interface in future versions without breaking source or binary compatibility with existing implementations of that interface.

Diese ähneln den "Standardmethoden"von Java.These are similar to Java's "Default Methods".

(Basierend auf dem wahrscheinlichen Implementierungs Verfahren) erfordert dieses Feature entsprechende Unterstützung in der CLI/CLR.(Based on the likely implementation technique) this feature requires corresponding support in the CLI/CLR. Programme, die dieses Feature nutzen, können in früheren Versionen der Plattform nicht ausgeführt werden.Programs that take advantage of this feature cannot run on earlier versions of the platform.

MotivationMotivation

Die Hauptgründe für dieses Feature sindThe principal motivations for this feature are

Detaillierter EntwurfDetailed design

Die Syntax für eine Schnittstelle wird auf zulassen erweitert.The syntax for an interface is extended to permit

  • Member-Deklarationen, die Konstanten, Operatoren, statische Konstruktoren und die Typen von Typen deklarieren.member declarations that declare constants, operators, static constructors, and nested types;
  • ein Text für eine Methode oder einen Indexer, eine Eigenschaft oder einen Ereignis Accessor (d. h. eine "Default"-Implementierung);a body for a method or indexer, property, or event accessor (that is, a "default" implementation);
  • Member-Deklarationen, die statische Felder, Methoden, Eigenschaften, Indexer und Ereignisse deklarieren.member declarations that declare static fields, methods, properties, indexers, and events;
  • Member-Deklarationen mit der expliziten Schnittstellen Implementierungs Syntax; immermember declarations using the explicit interface implementation syntax; and
  • Explizite Zugriffsmodifizierer (der Standard Zugriff ist public).Explicit access modifiers (the default access is public).

Member mit Text ermöglichen der-Schnittstelle, eine "Default"-Implementierung für die Methode in Klassen und Strukturen bereitzustellen, die keine über schreibende Implementierung bereitstellen.Members with bodies permit the interface to provide a "default" implementation for the method in classes and structs that do not provide an overriding implementation.

Schnittstellen dürfen keinen Instanzstatus enthalten.Interfaces may not contain instance state. Obwohl statische Felder jetzt zulässig sind, sind Instanzfelder in Schnittstellen nicht zulässig.While static fields are now permitted, instance fields are not permitted in interfaces. Automatische Instanzeigenschaften werden in Schnittstellen nicht unterstützt, da Sie implizit ein ausgeblendetes Feld deklarieren würden.Instance auto-properties are not supported in interfaces, as they would implicitly declare a hidden field.

Statische und private Methoden ermöglichen ein nützliches Refactoring und eine Organisation des Codes, der zum Implementieren der öffentlichen API der Schnittstelle verwendet wird.Static and private methods permit useful refactoring and organization of code used to implement the interface's public API.

Eine Methoden Überschreibung in einer Schnittstelle muss die explizite Schnittstellen Implementierungs Syntax verwenden.A method override in an interface must use the explicit interface implementation syntax.

Es ist ein Fehler, einen Klassentyp, Strukturtyp oder Enumerationstyp innerhalb des Gültigkeits Bereichs eines Typparameters zu deklarieren, der mit einem variance_annotationdeklariert wurde.It is an error to declare a class type, struct type, or enum type within the scope of a type parameter that was declared with a variance_annotation. Beispielsweise ist die Deklaration von C unten ein Fehler.For example, the declaration of C below is an error.

interface IOuter<out T>
{
    class C { } // error: class declaration within the scope of variant type parameter 'T'
}

Konkrete Methoden in SchnittstellenConcrete methods in interfaces

Die einfachste Form dieses Features ist die Möglichkeit, eine konkrete Methode in einer Schnittstelle zu deklarieren, bei der es sich um eine Methode mit einem Text handelt.The simplest form of this feature is the ability to declare a concrete method in an interface, which is a method with a body.

interface IA
{
    void M() { WriteLine("IA.M"); }
}

Eine Klasse, die diese Schnittstelle implementiert, muss Ihre konkrete Methode nicht implementieren.A class that implements this interface need not implement its concrete method.

class C : IA { } // OK

IA i = new C();
i.M(); // prints "IA.M"

Die abschließende außer Kraft setzung für IA.M in Class C ist die konkrete Methode M die in IAdeklariert wurde.The final override for IA.M in class C is the concrete method M declared in IA. Beachten Sie, dass eine Klasse keine Member von ihren Schnittstellen erbt. Dies wird von dieser Funktion nicht geändert:Note that a class does not inherit members from its interfaces; that is not changed by this feature:

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

In einem Instanzmember einer Schnittstelle hat this den Typ der einschließenden Schnittstelle.Within an instance member of an interface, this has the type of the enclosing interface.

Modifiziererer in SchnittstellenModifiers in interfaces

Die Syntax für eine Schnittstelle wird gelockert, um modifiziererer auf ihren Membern zuzulassen.The syntax for an interface is relaxed to permit modifiers on its members. Folgendes ist zulässig: private, protected, internal, public, virtual, abstract, sealed, static, externund partial.The following are permitted: private, protected, internal, public, virtual, abstract, sealed, static, extern, and partial.

TODO: Überprüfen Sie, welche anderen modifiziererer vorhanden sind.TODO: check what other modifiers exist.

Ein Schnittstellenmember, dessen Deklaration einen Text enthält, ist ein virtual Member, es sei denn, der sealed oder private Modifizierer wird verwendetAn interface member whose declaration includes a body is a virtual member unless the sealed or private modifier is used. Der virtual Modifizierer kann auf einem Funktionsmember verwendet werden, der andernfalls implizit virtualwäre.The virtual modifier may be used on a function member that would otherwise be implicitly virtual. Auch wenn abstract der Standardwert für Schnittstellenmember ohne Text ist, kann dieser Modifizierer explizit angegeben werden.Similarly, although abstract is the default on interface members without bodies, that modifier may be given explicitly. Ein nicht virtuelles Member kann mit dem sealed-Schlüsselwort deklariert werden.A non-virtual member may be declared using the sealed keyword.

Es ist ein Fehler bei einem private oder sealed Funktionsmember einer Schnittstelle, dass kein Text vorhanden ist.It is an error for a private or sealed function member of an interface to have no body. Ein private Funktionsmember verfügt möglicherweise nicht über den-Modifizierer sealed.A private function member may not have the modifier sealed.

Zugriffsmodifizierer können für Schnittstellenmember aller zulässigen Member verwendet werden.Access modifiers may be used on interface members of all kinds of members that are permitted. Die Zugriffsebene public ist die Standardeinstellung, kann aber explizit angegeben werden.The access level public is the default but it may be given explicitly.

Problem öffnen: Wir müssen die genaue Bedeutung der Zugriffsmodifizierer angeben, z. b. protected und internal. Außerdem müssen Sie angeben, welche Deklarationen Sie (in einer abgeleiteten Schnittstelle) überschreiben oder implementieren (in einer Klasse, die die-Schnittstelle implementiert).Open Issue: We need to specify the precise meaning of the access modifiers such as protected and internal, and which declarations do and do not override them (in a derived interface) or implement them (in a class that implements the interface).

Schnittstellen können static Member deklarieren, einschließlich der Typen, Methoden, Indexer, Eigenschaften, Ereignisse und statischen Konstruktoren.Interfaces may declare static members, including nested types, methods, indexers, properties, events, and static constructors. Die Standard Zugriffsebene für alle Schnittstellenmember ist public.The default access level for all interface members is public.

Schnittstellen können keine Instanzkonstruktoren, Dekonstruktoren oder Felder deklarieren.Interfaces may not declare instance constructors, destructors, or fields.

Geschlossene Probleme: Sollten Operator Deklarationen in einer Schnittstelle zulässig sein?Closed Issue: Should operator declarations be permitted in an interface? Wahrscheinlich keine Konvertierungs Operatoren, aber was ist mit anderen?Probably not conversion operators, but what about others? Entscheidung: Operatoren sind mit Ausnahme von Konvertierungs-, Gleichheits-und Ungleichheits Operatoren zulässig.Decision: Operators are permitted except for conversion, equality, and inequality operators.

Geschlossene Probleme: Sollten new für Schnittstellenmember-Deklarationen zulässig sein, die Member von Basis Schnittstellen ausblenden?Closed Issue: Should new be permitted on interface member declarations that hide members from base interfaces? Entscheidung: Ja.Decision: Yes.

Geschlossene Probleme: Wir gestatten derzeit keine partial auf einer Schnittstelle oder ihren Membern.Closed Issue: We do not currently permit partial on an interface or its members. Dies erfordert einen separaten Vorschlag.That would require a separate proposal. Entscheidung: Ja.Decision: Yes. https://github.com/dotnet/csharplang/blob/master/meetings/2018/LDM-2018-10-17.md#permit-partial-in-interface

Über Schreibungen in SchnittstellenOverrides in interfaces

Überschreibungs Deklarationen (d. h. solche, die den override Modifizierer enthalten) ermöglichen es dem Programmierer, eine spezifischere Implementierung eines virtuellen Members in einer Schnittstelle bereitzustellen, auf der der Compiler oder die Laufzeit andernfalls keinen finden würde.Override declarations (i.e. those containing the override modifier) allow the programmer to provide a most specific implementation of a virtual member in an interface where the compiler or runtime would not otherwise find one. Außerdem ermöglicht es die Umwandlung eines abstrakten Members aus einer Super Schnittstelle in ein Standardelement in einer abgeleiteten Schnittstelle.It also allows turning an abstract member from a super-interface into a default member in a derived interface. Eine Überschreibungs Deklaration ist berechtigt, eine bestimmte Basis Schnittstellen Methode explizit zu überschreiben, indem Sie die Deklaration mit dem Schnittstellennamen qualifiziert (in diesem Fall ist kein Zugriffsmodifizierer zulässig).An override declaration is permitted to explicitly override a particular base interface method by qualifying the declaration with the interface name (no access modifier is permitted in this case). Implizite über schreibungen sind nicht zulässig.Implicit overrides are not permitted.

interface IA
{
    void M() { WriteLine("IA.M"); }
}
interface IB : IA
{
    override void IA.M() { WriteLine("IB.M"); } // explicitly named
}
interface IC : IA
{
    override void M() { WriteLine("IC.M"); } // implicitly named
}

Überschreibungs Deklarationen in Schnittstellen können nicht als sealeddeklariert werden.Override declarations in interfaces may not be declared sealed.

Öffentliche virtual Funktionsmember in einer Schnittstelle können in einer abgeleiteten Schnittstelle explizit überschrieben werden (indem Sie den Namen in der Überschreibungs Deklaration mit dem Schnittstellentyp qualifizieren, der die Methode ursprünglich deklariert hat, und einen Zugriffsmodifizierer weggelassen).Public virtual function members in an interface may be overridden in a derived interface explicitly (by qualifying the name in the override declaration with the interface type that originally declared the method, and omitting an access modifier).

virtual Funktionsmember in einer Schnittstelle können nur explizit (nicht implizit) in abgeleiteten Schnittstellen überschrieben werden, und Member, die nicht public sind, können nur in einer Klasse oder Struktur explizit (nicht implizit) implementiert werden.virtual function members in an interface may only be overridden explicitly (not implicitly) in derived interfaces, and members that are not public may only be implemented in a class or struct explicitly (not implicitly). In beiden Fällen muss auf den überschriebenen oder implementierten Member zugegriffen werden können , wo er überschrieben wurde.In either case, the overridden or implemented member must be accessible where it is overridden.

NeuabstraktionReabstraction

Eine in einer Schnittstelle deklarierte virtuelle (konkrete) Methode kann in einer abgeleiteten Schnittstelle als abstrakt überschrieben werden.A virtual (concrete) method declared in an interface may be overridden to be abstract in a derived interface

interface IA
{
    void M() { WriteLine("IA.M"); }
}
interface IB : IA
{
    abstract void IA.M();
}
class C : IB { } // error: class 'C' does not implement 'IA.M'.

Der abstract Modifizierer ist in der Deklaration von IB.M nicht erforderlich (Dies ist die Standardeinstellung in-Schnittstellen), aber es ist wahrscheinlich empfehlenswert, explizit in einer Überschreibungs Deklaration zu sein.The abstract modifier is not required in the declaration of IB.M (that is the default in interfaces), but it is probably good practice to be explicit in an override declaration.

Dies ist in abgeleiteten Schnittstellen nützlich, bei denen die Standard Implementierung einer Methode ungeeignet ist und eine geeignetere Implementierung durch Implementieren von Klassen bereitgestellt werden sollte.This is useful in derived interfaces where the default implementation of a method is inappropriate and a more appropriate implementation should be provided by implementing classes.

Problem öffnen: Sollte eine erneute Abstraktion zulässig sein?Open Issue: Should reabstraction be permitted?

Die spezifischsten Überschreibungs RegelThe most specific override rule

Wir verlangen, dass jede Schnittstelle und Klasse über eine spezifischere außer Kraft setzung für jedes virtuelle Element unter den außer Kraft setzungen verfügen, die im Typ oder seinen direkten und indirekten Schnittstellen angezeigt werden.We require that every interface and class have a most specific override for every virtual member among the overrides appearing in the type or its direct and indirect interfaces. Die spezifischere außer Kraft Setzung ist eine eindeutige außer Kraft setzung, die spezifischer ist als jede andere außer Kraft Setzung.The most specific override is a unique override that is more specific than every other override. Wenn keine außer Kraft Setzung vorhanden ist, wird der Member selbst als die spezifischsten außer Kraft Setzung betrachtet.If there is no override, the member itself is considered the most specific override.

Eine außer Kraft Setzung M1 gilt als spezifischere als eine andere außer Kraft Setzung M2 wenn M1 für den Typ T1deklariert ist, M2 für den Typ T2deklariert ist, und entwederOne override M1 is considered more specific than another override M2 if M1 is declared on type T1, M2 is declared on type T2, and either

  1. T1 enthält T2 zu den direkten oder indirekten Schnittstellen.T1 contains T2 among its direct or indirect interfaces, or
  2. T2 ist ein Schnittstellentyp, aber T1 ist kein Schnittstellentyp.T2 is an interface type but T1 is not an interface type.

Beispiel:For example:

interface IA
{
    void M() { WriteLine("IA.M"); }
}
interface IB : IA
{
    void IA.M() { WriteLine("IB.M"); }
}
interface IC : IA
{
    void IA.M() { WriteLine("IC.M"); }
}
interface ID : IB, IC { } // error: no most specific override for 'IA.M'
abstract class C : IB, IC { } // error: no most specific override for 'IA.M'
abstract class D : IA, IB, IC // ok
{
    public abstract void M();
}

Die spezifischere Überschreibungs Regel stellt sicher, dass ein Konflikt (d. h. eine Mehrdeutigkeit durch die rautenvererbung) explizit vom Programmierer an dem Punkt aufgelöst wird, an dem der Konflikt auftritt.The most specific override rule ensures that a conflict (i.e. an ambiguity arising from diamond inheritance) is resolved explicitly by the programmer at the point where the conflict arises.

Da wir explizite abstrakte über Schreibungen in Schnittstellen unterstützen, können wir dies auch in Klassen tun.Because we support explicit abstract overrides in interfaces, we could do so in classes as well

abstract class E : IA, IB, IC // ok
{
    abstract void IA.M();
}

Open Issue: sollten explizite Schnittstellen abstrakte über Schreibungen in Klassen unterstützt werden?Open issue: should we support explicit interface abstract overrides in classes?

Außerdem ist es ein Fehler, wenn in einer Klassen Deklaration die spezifischere außer Kraft Setzung einer Schnittstellen Methode eine abstrakte außer Kraft Setzung ist, die in einer Schnittstelle deklariert wurde.In addition, it is an error if in a class declaration the most specific override of some interface method is an abstract override that was declared in an interface. Dies ist eine vorhandene Regel, die mithilfe der neuen Terminologie neu angegeben wurde.This is an existing rule restated using the new terminology.

interface IF
{
    void M();
}
abstract class F : IF { } // error: 'F' does not implement 'IF.M'

Eine in einer Schnittstelle deklarierte virtuelle Eigenschaft kann eine spezifischere außer Kraft setzung für den get Accessor in einer Schnittstelle und eine spezifischere außer Kraft setzung für den set Accessor in einer anderen Schnittstelle aufweisen.It is possible for a virtual property declared in an interface to have a most specific override for its get accessor in one interface and a most specific override for its set accessor in a different interface. Dies wird als Verstoß gegen die spezifischsten Überschreibungs Regel angesehen.This is considered a violation of the most specific override rule.

Die Methoden static und privatestatic and private methods

Da Schnittstellen nun ausführbaren Code enthalten können, ist es hilfreich, allgemeinen Code in private und statische Methoden zu abstrahieren.Because interfaces may now contain executable code, it is useful to abstract common code into private and static methods. Diese werden jetzt in Schnittstellen zugelassen.We now permit these in interfaces.

Geschlossenes Problem: sollen private Methoden unterstützt werden?Closed issue: Should we support private methods? Sollten statische Methoden unterstützt werden?Should we support static methods? Entscheidung: JaDecision: YES

Open Issue: sollen Schnittstellen Methoden protected oder internal oder andere Zugriffsberechtigungen zugelassen werden?Open issue: should we permit interface methods to be protected or internal or other access? Wenn dies der Fall ist, wie lautet die Semantik?If so, what are the semantics? Sind Sie standardmäßig virtual?Are they virtual by default? Wenn dies der Fall ist, gibt es eine Möglichkeit, Sie als nicht virtuell zu gestalten?If so, is there a way to make them non-virtual?

Open Issue: Wenn statische Methoden unterstützt werden, sollten (statische) Operatoren unterstützt werden?Open issue: If we support static methods, should we support (static) operators?

Basis Schnittstellen AufrufeBase interface invocations

Code in einem Typ, der von einer Schnittstelle mit einer Standardmethode abgeleitet ist, kann die "Base"-Implementierung dieser Schnittstelle explizit aufrufen.Code in a type that derives from an interface with a default method can explicitly invoke that interface's "base" implementation.

interface I0
{
   void M() { Console.WriteLine("I0"); }
}
interface I1 : I0
{
   override void M() { Console.WriteLine("I1"); }
}
interface I2 : I0
{
   override void M() { Console.WriteLine("I2"); }
}
interface I3 : I1, I2
{
   // an explicit override that invoke's a base interface's default method
   void I0.M() { I2.base.M(); }
}

Eine Instanzmethode (nicht statisch) kann die Implementierung einer zugänglichen Instanzmethode in einer direkten Basisschnittstelle nicht virtuell aufrufen, indem Sie Sie mit der Syntax base(Type).Mbenennt.An instance (nonstatic) method is permitted to invoke the implementation of an accessible instance method in a direct base interface nonvirtually by naming it using the syntax base(Type).M. Dies ist hilfreich, wenn eine außer Kraft setzung, die aufgrund der rautenvererbung bereitgestellt werden muss, durch Delegieren an eine bestimmte Basis Implementierung aufgelöst wird.This is useful when an override that is required to be provided due to diamond inheritance is resolved by delegating to one particular base implementation.

interface IA
{
    void M() { WriteLine("IA.M"); }
}
interface IB : IA
{
    override void IA.M() { WriteLine("IB.M"); }
}
interface IC : IA
{
    override void IA.M() { WriteLine("IC.M"); }
}

class D : IA, IB, IC
{
    void IA.M() { base(IB).M(); }
}

Wenn auf eine virtual oder abstract Member mithilfe der Syntax base(Type).Mzugegriffen wird, ist es erforderlich, dass Type eine eindeutige außer Kraft setzung für Menthält.When a virtual or abstract member is accessed using the syntax base(Type).M, it is required that Type contains a unique most specific override for M.

Bindungs Basis KlauselnBinding base clauses

Schnittstellen enthalten nun Typen.Interfaces now contain types. Diese Typen können in der Base-Klausel als Basis Schnittstellen verwendet werden.These types may be used in the base clause as base interfaces. Beim Binden einer Basis Klausel müssen wir möglicherweise den Satz von Basis Schnittstellen kennen, um diese Typen zu binden (z. b. um Nachrichten zu suchen und geschützten Zugriff aufzulösen).When binding a base clause, we may need to know the set of base interfaces to bind those types (e.g. to lookup in them and to resolve protected access). Die Bedeutung der Basis Klausel einer Schnittstelle wird daher zirkulär definiert.The meaning of an interface's base clause is thus circularly defined. Um den Kreis zu unterbrechen, fügen wir eine neue Sprachregel hinzu, die einer ähnlichen Regel entspricht, die für Klassen bereits vorhanden ist.To break the cycle, we add a new language rules corresponding to a similar rule already in place for classes.

Beim Ermitteln der Bedeutung des interface_base einer Schnittstelle wird davon ausgegangen, dass die Basis Schnittstellen temporär leer sind.While determining the meaning of the interface_base of an interface, the base interfaces are temporarily assumed to be empty. Intuitiv wird dadurch sichergestellt, dass die Bedeutung einer Basis Klausel nicht rekursiv von sich selbst abhängig ist.Intuitively this ensures that the meaning of a base clause cannot recursively depend on itself.

Wir haben die folgenden Regeln verwendet:We used to have the following rules:

"Wenn eine Klasse B von einer Klasse a abgeleitet ist, ist dies ein Kompilierzeitfehler für eine, die von B abhängig ist. Eine Klasse hängt direkt von ihrer direkten Basisklasse (sofern vorhanden) ab und hängt direkt von der Klasse ab, in der Sie sofort geschachtelt ist (sofern vorhanden)."When a class B derives from a class A, it is a compile-time error for A to depend on B. A class directly depends on its direct base class (if any) and directly depends on the class within which it is immediately nested (if any). Bei dieser Definition ist der gesamte Satz von Klassen , von dem eine Klasse abhängt, die reflexive und transitiv Schließung der direkt von der Beziehung abhängig. "Given this definition, the complete set of classes upon which a class depends is the reflexive and transitive closure of the directly depends on relationship."

Es ist ein Kompilierzeitfehler für eine Schnittstelle, die direkt oder indirekt von sich selbst erbt.It is a compile-time error for an interface to directly or indirectly inherit from itself. Die Basis Schnittstellen einer Schnittstelle sind die expliziten Basis Schnittstellen und deren Basis Schnittstellen.The base interfaces of an interface are the explicit base interfaces and their base interfaces. Mit anderen Worten: der Satz von Basis Schnittstellen ist die komplette transitiv Schließung der expliziten Basis Schnittstellen, ihrer expliziten Basis Schnittstellen usw.In other words, the set of base interfaces is the complete transitive closure of the explicit base interfaces, their explicit base interfaces, and so on.

Wir passen Sie wie folgt an:We are adjusting them as follows:

Wenn eine Klasse B von einer Klasse a abgeleitet ist, ist dies ein Kompilierzeitfehler für eine, die von B abhängig ist. Eine Klasse hängt direkt von ihrer direkten Basisklasse (sofern vorhanden) ab und hängt direkt von dem Typ ab, in dem Sie sofort geschachtelt ist (sofern vorhanden).When a class B derives from a class A, it is a compile-time error for A to depend on B. A class directly depends on its direct base class (if any) and directly depends on the type within which it is immediately nested (if any).

Wenn ein Interface-IB eine Interface IA erweitert, handelt es sich um einen Kompilierzeitfehler, damit IA von IB abhängig ist.When an interface IB extends an interface IA, it is a compile-time error for IA to depend on IB. Eine Schnittstelle hängt direkt von ihren direkten Basis Schnittstellen (sofern vorhanden) ab und hängt direkt von dem Typ ab, in dem Sie sofort geschachtelt ist (sofern vorhanden).An interface directly depends on its direct base interfaces (if any) and directly depends on the type within which it is immediately nested (if any).

Bei diesen Definitionen ist der gesamte Satz von Typen , von dem ein Typ abhängt, der reflexive und transitiv Abschluss der direkt von Beziehung abhängig.Given these definitions, the complete set of types upon which a type depends is the reflexive and transitive closure of the directly depends on relationship.

Auswirkung auf vorhandene ProgrammeEffect on existing programs

Die hier vorgestellten Regeln sollen keine Auswirkung auf die Bedeutung vorhandener Programme haben.The rules presented here are intended to have no effect on the meaning of existing programs.

Beispiel 1:Example 1:

interface IA
{
    void M();
}
class C: IA // Error: IA.M has no concrete most specific override in C
{
    public static void M() { } // method unrelated to 'IA.M' because static
}

Beispiel 2:Example 2:

interface IA
{
    void M();
}
class Base: IA
{
    void IA.M() { }
}
class Derived: Base, IA // OK, all interface members have a concrete most specific override
{
    private void M() { } // method unrelated to 'IA.M' because private
}

Die gleichen Regeln führen zu ähnlichen Ergebnissen wie bei den Standardschnittstellen Methoden:The same rules give similar results to the analogous situation involving default interface methods:

interface IA
{
    void M() { }
}
class Derived: IA // OK, all interface members have a concrete most specific override
{
    private void M() { } // method unrelated to 'IA.M' because private
}

Geschlossenes Problem: Vergewissern Sie sich, dass dies eine beabsichtigte Folge der Spezifikation ist.Closed issue: confirm that this is an intended consequence of the specification. Entscheidung: JaDecision: YES

Auflösung der Lauf Zeit MethodeRuntime method resolution

Geschlossene Probleme: Die Spezifikation sollte den Algorithmus zur Auflösung der Lauf Zeit Methode im Gesicht der Standardmethoden der Schnittstelle beschreiben.Closed Issue: The spec should describe the runtime method resolution algorithm in the face of interface default methods. Wir müssen sicherstellen, dass die Semantik mit der sprach Semantik konsistent ist, z. b. welche deklarierten Methoden dies tun und keine internal Methode überschreiben oder implementieren.We need to ensure that the semantics are consistent with the language semantics, e.g. which declared methods do and do not override or implement an internal method.

CLR-Support-APICLR support API

Damit Compiler erkennen können, dass Sie für eine Laufzeit kompiliert werden, die diese Funktion unterstützt, werden Bibliotheken für diese Laufzeiten so geändert, dass diese Fakten über die in https://github.com/dotnet/corefx/issues/17116erörterte API angekündigt werden.In order for compilers to detect when they are compiling for a runtime that supports this feature, libraries for such runtimes are modified to advertise that fact through the API discussed in https://github.com/dotnet/corefx/issues/17116. Wir fügenWe add

namespace System.Runtime.CompilerServices
{
    public static class RuntimeFeature
    {
        // Presence of the field indicates runtime support
        public const string DefaultInterfaceImplementation = nameof(DefaultInterfaceImplementation);
    }
}

Open Issue: ist der beste Name für die CLR -Funktion?Open issue: Is that the best name for the CLR feature? Die CLR-Funktion ist viel mehr als nur das (z. b. lockern von Schutz Einschränkungen, unterstützt über Schreibungen in Schnittstellen usw.).The CLR feature does much more than just that (e.g. relaxes protection constraints, supports overrides in interfaces, etc). Vielleicht sollte Sie z. b. "konkrete Methoden in Schnittstellen" oder "Merkmale" genannt werden?Perhaps it should be called something like "concrete methods in interfaces", or "traits"?

Weitere Bereiche, die angegeben werden sollenFurther areas to be specified

  • [] Es ist hilfreich, die Arten von Quell-und Binär Kompatibilitäts Effekten zu katalogisieren, die durch das Hinzufügen von Standardschnittstellen Methoden und über schreibungen zu vorhandenen Schnittstellen verursacht werden.[ ] It would be useful to catalog the kinds of source and binary compatibility effects caused by adding default interface methods and overrides to existing interfaces.

NachteileDrawbacks

Dieser Vorschlag erfordert ein koordiniertes Update der CLR-Spezifikation (zur Unterstützung konkreter Methoden in Schnittstellen und Methoden Auflösung).This proposal requires a coordinated update to the CLR specification (to support concrete methods in interfaces and method resolution). Es ist daher ziemlich "teuer", und es kann sinnvoll sein, in Kombination mit anderen Features, die wir erwarten, CLR-Änderungen zu erfordern.It is therefore fairly "expensive" and it may be worth doing in combination with other features that we also anticipate would require CLR changes.

AlternativenAlternatives

None.None.

Nicht aufgelöste FragenUnresolved questions

  • Offene Fragen werden im obigen Vorschlag genannt.Open questions are called out throughout the proposal, above.
  • Eine Liste der offenen Fragen finden Sie unter https://github.com/dotnet/csharplang/issues/406.See also https://github.com/dotnet/csharplang/issues/406 for a list of open questions.
  • Die ausführliche Spezifikation muss den Auflösungs Mechanismus beschreiben, der zur Laufzeit verwendet wird, um die genaue Methode auszuwählen, die aufgerufen werden soll.The detailed specification must describe the resolution mechanism used at runtime to select the precise method to be invoked.
  • Die Interaktion von Metadaten, die von neuen Compilern erzeugt und von älteren Compilern genutzt werden, muss ausführlich verarbeitet werden.The interaction of metadata produced by new compilers and consumed by older compilers needs to be worked out in detail. Beispielsweise müssen wir sicherstellen, dass die von uns verwendete Metadatendarstellung nicht bewirkt, dass eine Standard Implementierung in einer Schnittstelle hinzugefügt wird, um eine vorhandene Klasse zu unterbrechen, die diese Schnittstelle implementiert, wenn Sie von einem älteren Compiler kompiliert wird.For example, we need to ensure that the metadata representation that we use does not cause the addition of a default implementation in an interface to break an existing class that implements that interface when compiled by an older compiler. Dies kann sich auf die Metadatendarstellung auswirken, die wir verwenden können.This may affect the metadata representation that we can use.
  • Der Entwurf muss die Interoperation mit anderen Sprachen und vorhandenen Compilern für andere Sprachen in Erwägung gezogen werden.The design must consider interoperation with other languages and existing compilers for other languages.

Aufgelöste FragenResolved Questions

Abstrakte außer Kraft SetzungAbstract Override

Die vorherige Entwurfs Spezifikation enthielt die Möglichkeit, eine geerbte Methode "reabstract" zu erstellen:The earlier draft spec contained the ability to "reabstract" an inherited method:

interface IA
{
    void M();
}
interface IB : IA
{
    override void M() { }
}
interface IC : IB
{
    override void M(); // make it abstract again
}

Meine Notizen für 2017-03-20 haben ergeben, dass wir dies nicht zulassen.My notes for 2017-03-20 showed that we decided not to allow this. Hierfür gibt es jedoch mindestens zwei Anwendungsfälle:However, there are at least two use cases for it:

  1. Die Java-APIs, mit denen einige Benutzer dieses Features zusammenarbeiten, sind von dieser Funktion abhängig.The Java APIs, with which some users of this feature hope to interoperate, depend on this facility.
  2. Die Programmierung mit Merkmalen profitiert davon.Programming with traits benefits from this. Reabstraktion ist eines der Elemente der Sprachfunktion "Merkmale" (https://en.wikipedia.org/wiki/Trait_(computer_programming)).Reabstraction is one of the elements of the "traits" language feature (https://en.wikipedia.org/wiki/Trait_(computer_programming)). Die folgenden Klassen sind zulässig:The following is permitted with classes:
public abstract class Base
{
    public abstract void M();
}
public abstract class A : Base
{
    public override void M() { }
}
public abstract class B : A
{
    public override abstract void M(); // reabstract Base.M
}

Leider kann dieser Code nicht als Satz von Schnittstellen (Merkmalen) umgestaltet werden, es sei denn, dies ist zulässig.Unfortunately this code cannot be refactored as a set of interfaces (traits) unless this is permitted. Das Jared-Prinzip der Giersollte zugelassen werden.By the Jared principle of greed, it should be permitted.

Geschlossene Probleme: Sollte eine erneute Abstraktion zulässig sein?Closed issue: Should reabstraction be permitted? Zwar Meine Notizen waren falsch.[YES] My notes were wrong. Die LDM bemerkt , dass eine erneute Abstraktion in einer Schnittstelle zulässig ist.The LDM notes say that reabstraction is permitted in an interface. Nicht in einer Klasse.Not in a class.

Virtueller Modifizierer vs sealed-ModifiziererVirtual Modifier vs Sealed Modifier

Aus Aleksey tsingauz:From Aleksey Tsingauz:

Es wurde beschlossen, Modifizierer explizit für Schnittstellenmember anzugeben, es sei denn, es gibt einen Grund dafür, einige davon zu unterbinden.We decided to allow modifiers explicitly stated on interface members, unless there is a reason to disallow some of them. Dies bringt eine interessante Frage in Bezug auf den virtuellen Modifizierer.This brings an interesting question around virtual modifier. Sollte es für Member mit Standard Implementierung erforderlich sein?Should it be required on members with default implementation?

Wir könnten Folgendes sagen:We could say that:

  • Wenn keine Implementierung vorhanden ist und weder Virtual noch Sealed angegeben sind, wird davon ausgegangen, dass der Member abstrakt ist.if there is no implementation and neither virtual, nor sealed are specified, we assume the member is abstract.
  • Wenn eine Implementierung vorhanden ist und weder abstract noch Sealed angegeben sind, wird davon ausgegangen, dass der Member virtuell ist.if there is an implementation and neither abstract, nor sealed are specified, we assume the member is virtual.
  • der sealed-Modifizierer ist erforderlich, um eine Methode weder virtuell noch abstrakt zu machen.sealed modifier is required to make a method neither virtual, nor abstract.

Wir könnten auch sagen, dass der virtuelle Modifizierer für ein virtuelles Element erforderlich ist.Alternatively, we could say that virtual modifier is required for a virtual member. Wenn also ein Member vorhanden ist, dessen Implementierung nicht explizit mit dem virtuellen Modifizierer markiert ist, ist es weder virtuell noch abstrakt.I.e, if there is a member with implementation not explicitly marked with virtual modifier, it is neither virtual, nor abstract. Diese Vorgehensweise bietet möglicherweise eine bessere Leistung, wenn eine Methode von einer Klasse zu einer Schnittstelle verschoben wird:This approach might provide better experience when a method is moved from a class to an interface:

  • eine abstrakte Methode bleibt abstrakt.an abstract method stays abstract.
  • eine virtuelle Methode bleibt virtuell.a virtual method stays virtual.
  • eine Methode ohne einen Modifizierer bleibt weder virtuell noch abstrakt.a method without any modifier stays neither virtual, nor abstract.
  • der sealed-Modifizierer kann nicht auf eine Methode angewendet werden, die keine außer Kraft Setzung ist.sealed modifier cannot be applied to a method that is not an override.

Was denkst du?What do you think?

Geschlossene Probleme: Sollte eine konkrete Methode (mit Implementierung) implizit virtualwerden?Closed Issue: Should a concrete method (with implementation) be implicitly virtual? Zwar[YES]

Entscheidungen: Erstellt in LDM 2017-04-05:Decisions: Made in the LDM 2017-04-05:

  1. nicht virtuell sollte explizit durch sealed oder privateausgedrückt werden.non-virtual should be explicitly expressed through sealed or private.
  2. sealed ist das Schlüsselwort, um schnittstelleninstanzmember mit nicht virtuellen Text Schnittstellen zu erstellen.sealed is the keyword to make interface instance members with bodies non-virtual
  3. Wir möchten alle modifiziererer in Schnittstellen zulassen.We want to allow all modifiers in interfaces
  4. Der Standard Zugriff für Schnittstellenmember ist öffentlich, einschließlich der UntertypenDefault accessibility for interface members is public, including nested types
  5. Private Funktionsmember in Schnittstellen sind implizit versiegelt, und sealed ist für Sie nicht zulässig.private function members in interfaces are implicitly sealed, and sealed is not permitted on them.
  6. Private Klassen (in Schnittstellen) sind zulässig und können versiegelt werden, und das bedeutet versiegelt in der Klassen Sense Sealed.Private classes (in interfaces) are permitted and can be sealed, and that means sealed in the class sense of sealed.
  7. Wenn kein gutes Angebot vorhanden ist, ist partiell bei Schnittstellen oder ihren Membern weiterhin nicht zulässig.Absent a good proposal, partial is still not allowed on interfaces or their members.

Binäre Kompatibilität 1Binary Compatibility 1

Wenn eine Bibliothek eine Standard Implementierung bereitstelltWhen a library provides a default implementation

interface I1
{
    void M() { Impl1 }
}
interface I2 : I1
{
}
class C : I2
{
}

Wir wissen, dass die Implementierung von I1.M in C I1.Mist.We understand that the implementation of I1.M in C is I1.M. Was geschieht, wenn die Assembly, die I2 enthält, wie folgt geändert und neu kompiliert wird.What if the assembly containing I2 is changed as follows and recompiled

interface I2 : I1
{
    override void M() { Impl2 }
}

C wird jedoch nicht neu kompiliert.but C is not recompiled. Was geschieht, wenn das Programm ausgeführt wird?What happens when the program is run? Ein Aufruf von (C as I1).M()An invocation of (C as I1).M()

  1. Führt I1.MRuns I1.M
  2. Führt I2.MRuns I2.M
  3. Löst einen Laufzeitfehler aus.Throws some kind of runtime error

Entscheidung: 2017-04-11: führt I2.Maus, bei dem es sich um die eindeutig spezifischere außer Kraft Setzung zur Laufzeit handelt.Decision: Made 2017-04-11: Runs I2.M, which is the unambiguously most specific override at runtime.

Ereignisaccessoren (geschlossen)Event accessors (closed)

Geschlossene Probleme: Kann ein Ereignis "schrittweise" überschrieben werden?Closed Issue: Can an event be overridden "piecewise"?

Beachten Sie diesen Fall:Consider this case:

public interface I1
{
    event T e1;
}
public interface I2 : I1
{
    override event T
    {
        add { }
        // error: "remove" accessor missing
    }
}

Diese "partielle" Implementierung des Ereignisses ist unzulässig, da die Syntax für eine Ereignis Deklaration, wie in einer Klasse, nicht nur einen Accessor zulässt. Beide (oder keine) müssen angegeben werden.This "partial" implementation of the event is not permitted because, as in a class, the syntax for an event declaration does not permit only one accessor; both (or neither) must be provided. Sie können das gleiche erreichen, indem Sie zulassen, dass der abstrakte remove-Accessor in der Syntax implizit abstrakt ist, wenn kein Text vorhanden ist:You could accomplish the same thing by permitting the abstract remove accessor in the syntax to be implicitly abstract by the absence of a body:

public interface I1
{
    event T e1;
}
public interface I2 : I1
{
    override event T
    {
        add { }
        remove; // implicitly abstract
    }
}

Beachten Sie, dass es sich hierbei um eine neue (vorgeschlagene) Syntax handelt.Note that this is a new (proposed) syntax. In der aktuellen Grammatik haben Ereignisaccessoren einen obligatorischen Text.In the current grammar, event accessors have a mandatory body.

Geschlossene Probleme: Kann ein Ereignis Accessor (implizit) durch das Weglassen eines Texts abstrahiert werden, ähnlich der Art, wie Methoden in Schnittstellen und Eigenschaftenaccessoren (implizit) durch das Weglassen eines Texts abstrakt sind?Closed Issue: Can an event accessor be (implicitly) abstract by the omission of a body, similarly to the way that methods in interfaces and property accessors are (implicitly) abstract by the omission of a body?

Entscheidung: (2017-04-18) Nein, Ereignis Deklarationen erfordern sowohl konkrete Accessoren (oder keines von beiden).Decision: (2017-04-18) No, event declarations require both concrete accessors (or neither).

Neuabstraktion in einer Klasse (geschlossen)Reabstraction in a Class (closed)

Geschlossene Probleme: Wir sollten bestätigen, dass dies zulässig ist (Andernfalls wäre das Hinzufügen einer Standard Implementierung eine Breaking Change):Closed Issue: We should confirm that this is permitted (otherwise adding a default implementation would be a breaking change):

interface I1
{
    void M() { }
}
abstract class C : I1
{
    public abstract void M(); // implement I1.M with an abstract method in C
}

Entscheidung: (2017-04-18) ja, das Hinzufügen eines Texts zu einer Schnittstellenmember-Deklaration sollte C nicht unterbrechen.Decision: (2017-04-18) Yes, adding a body to an interface member declaration shouldn't break C.

Versiegelte außer Kraft Setzung (geschlossen)Sealed Override (closed)

Die vorherige Frage geht implizit davon aus, dass der sealed Modifizierer auf eine override in einer Schnittstelle angewendet werden kann.The previous question implicitly assumes that the sealed modifier can be applied to an override in an interface. Dies widerspricht der Entwurfs Spezifikation.This contradicts the draft specification. Möchten wir das Versiegeln einer außer Kraft Setzung zulassen?Do we want to permit sealing an override? Die Auswirkungen auf die Quelle und die binäre Kompatibilität der Versiegelung sollten berücksichtigt werden.Source and binary compatibility effects of sealing should be considered.

Geschlossene Probleme: Sollten wir das Versiegeln einer außer Kraft Setzung zulassen?Closed Issue: Should we permit sealing an override?

Entscheidung: (2017-04-18) erlauben Sie keine sealed für außer Kraft setzungen in Schnittstellen.Decision: (2017-04-18) Let's not allowed sealed on overrides in interfaces. Die einzige Verwendung von sealed für Schnittstellenmember ist, dass Sie in ihrer ursprünglichen Deklaration nicht virtuell sind.The only use of sealed on interface members is to make them non-virtual in their initial declaration.

Rautenvererbung und-Klassen (geschlossen)Diamond inheritance and classes (closed)

Der Entwurf des Angebots bevorzugt die Außerkraftsetzungs Überschreibungen von Klassen in rautenvererbungs Szenarien:The draft of the proposal prefers class overrides to interface overrides in diamond inheritance scenarios:

Wir verlangen, dass jede Schnittstelle und Klasse eine spezifischere außer Kraft setzung für jede Schnittstellen Methode unter den außer Kraft setzungen aufweisen, die im Typ oder den direkten und indirekten Schnittstellen angezeigt werden.We require that every interface and class have a most specific override for every interface method among the overrides appearing in the type or its direct and indirect interfaces. Die spezifischere außer Kraft Setzung ist eine eindeutige außer Kraft setzung, die spezifischer ist als jede andere außer Kraft Setzung.The most specific override is a unique override that is more specific than every other override. Wenn keine außer Kraft Setzung vorhanden ist, wird die Methode selbst als die spezifischere außer Kraft Setzung betrachtet.If there is no override, the method itself is considered the most specific override.

Eine außer Kraft Setzung M1 gilt als spezifischere als eine andere außer Kraft Setzung M2 wenn M1 für den Typ T1deklariert ist, M2 für den Typ T2deklariert ist, und entwederOne override M1 is considered more specific than another override M2 if M1 is declared on type T1, M2 is declared on type T2, and either

  1. T1 enthält T2 zu den direkten oder indirekten Schnittstellen.T1 contains T2 among its direct or indirect interfaces, or
  2. T2 ist ein Schnittstellentyp, aber T1 ist kein Schnittstellentyp.T2 is an interface type but T1 is not an interface type.

Das Szenario istThe scenario is this

interface IA
{
    void M();
}
interface IB : IA
{
    override void M() { WriteLine("IB"); }
}
class Base : IA
{
    void IA.M() { WriteLine("Base"); }
}
class Derived : Base, IB // allowed?
{
    static void Main()
    {
        Ia a = new Derived();
        a.M();           // what does it do?
    }
}

Wir sollten dieses Verhalten bestätigen (oder andernfalls festlegen).We should confirm this behavior (or decide otherwise)

Geschlossene Probleme: Bestätigen Sie die oben beschriebene Entwurfs Spezifikation für die spezifischsten außer Kraft setzung, da Sie auf gemischte Klassen und Schnittstellen angewendet wird (eine Klasse hat Vorrang vor einer Schnittstelle).Closed Issue: Confirm the draft spec, above, for most specific override as it applies to mixed classes and interfaces (a class takes priority over an interface). Siehe https://github.com/dotnet/csharplang/blob/master/meetings/2017/LDM-2017-04-19.md#diamonds-with-classes.See https://github.com/dotnet/csharplang/blob/master/meetings/2017/LDM-2017-04-19.md#diamonds-with-classes.

Schnittstellen Methoden im Vergleich zu Strukturen (geschlossen)Interface methods vs structs (closed)

Es gibt einige unglückliche Interaktionen zwischen Standardschnittstellen Methoden und Strukturen.There are some unfortunate interactions between default interface methods and structs.

interface IA
{
    public void M() { }
}
struct S : IA
{
}

Beachten Sie, dass Schnittstellenmember nicht geerbt werden:Note that interface members are not inherited:

var s = default(S);
s.M(); // error: 'S' does not contain a member 'M'

Folglich muss der Client die Struktur zum Aufrufen von Schnittstellen Methoden in Box BoxConsequently, the client must box the struct to invoke interface methods

IA s = default(S); // an S, boxed
s.M(); // ok

Wenn Sie auf diese Weise Boxing, werden die Hauptvorteile eines struct Typs zunichte.Boxing in this way defeats the principal benefits of a struct type. Außerdem haben alle mutations Methoden keinen offensichtlichen Effekt, da Sie auf einer geachtelten Kopie der Struktur ausgeführt werden:Moreover, any mutation methods will have no apparent effect, because they are operating on a boxed copy of the struct:

interface IB
{
    public void Increment() { P += 1; }
    public int P { get; set; }
}
struct T : IB
{
    public int P { get; set; } // auto-property
}

T t = default(T);
Console.WriteLine(t.P); // prints 0
(t as IB).Increment();
Console.WriteLine(t.P); // prints 0

Geschlossene Probleme: Dazu können Sie Folgendes tun:Closed Issue: What can we do about this:

  1. Verbieten, dass eine struct eine Standard Implementierung erbt.Forbid a struct from inheriting a default implementation. Alle Schnittstellen Methoden werden in einem structals abstrakt behandelt.All interface methods would be treated as abstract in a struct. Dann können wir später einige Zeit in Anspruch nehmen, um die Arbeit zu verbessern.Then we may take time later to decide how to make it work better.
  2. Entwickeln Sie eine Art Code Generierungs Strategie, die Boxing vermeidet.Come up with some kind of code generation strategy that avoids boxing. Innerhalb einer Methode wie IB.Incrementwäre der Typ des this vielleicht vergleichbar mit einem Typparameter, der auf IBeingeschränkt ist.Inside a method like IB.Increment, the type of this would perhaps be akin to a type parameter constrained to IB. Um das Boxing im Aufrufer zu vermeiden, werden nicht abstrakte Methoden in Verbindung mit den Schnittstellen geerbt.In conjunction with that, to avoid boxing in the caller, non-abstract methods would be inherited from interfaces. Dadurch kann der Compiler und die CLR-Implementierung erheblich zunehmen.This may increase compiler and CLR implementation work substantially.
  3. Machen Sie sich keine Gedanken um die IT, und lassen Sie Sie einfach als wart.Not worry about it and just leave it as a wart.
  4. Weitere Ideen?Other ideas?

Entscheidung: Machen Sie sich keine Gedanken um die IT, und lassen Sie Sie einfach als wart.Decision: Not worry about it and just leave it as a wart. Siehe https://github.com/dotnet/csharplang/blob/master/meetings/2017/LDM-2017-04-19.md#structs-and-default-implementations.See https://github.com/dotnet/csharplang/blob/master/meetings/2017/LDM-2017-04-19.md#structs-and-default-implementations.

Basis Schnittstellen Aufrufe (geschlossen)Base interface invocations (closed)

Die Entwurfs Spezifikation schlägt eine Syntax für Basis Schnittstellen Aufrufe vor, die von Java inspiriert sind: Interface.base.M().The draft spec suggests a syntax for base interface invocations inspired by Java: Interface.base.M(). Wir müssen eine Syntax auswählen, zumindest für den anfänglichen Prototyp.We need to select a syntax, at least for the initial prototype. Mein Favorit ist base<Interface>.M().My favorite is base<Interface>.M().

Geschlossene Probleme: Was ist die Syntax für einen Basismember-Aufruf?Closed Issue: What is the syntax for a base member invocation?

Entscheidung: Die Syntax ist base(Interface).M().Decision: The syntax is base(Interface).M(). Siehe https://github.com/dotnet/csharplang/blob/master/meetings/2017/LDM-2017-04-19.md#base-invocation.See https://github.com/dotnet/csharplang/blob/master/meetings/2017/LDM-2017-04-19.md#base-invocation. Die Schnittstelle, die so benannt ist, muss eine Basisschnittstelle sein, es muss sich jedoch nicht um eine direkte Basisschnittstelle handeln.The interface so named must be a base interface, but does not need to be a direct base interface.

Problem öffnen: Sollten Basis Schnittstellen Aufrufe in Klassenmembern zulässig sein?Open Issue: Should base interface invocations be permitted in class members?

Entscheidung: Ja.Decision: Yes. https://github.com/dotnet/csharplang/blob/master/meetings/2017/LDM-2017-04-19.md#base-invocation

Überschreiben von nicht öffentlichen Schnittstellenmembern (geschlossen)Overriding non-public interface members (closed)

In einer Schnittstelle werden nicht öffentliche Member von Basis Schnittstellen mithilfe des override Modifizierers überschrieben.In an interface, non-public members from base interfaces are overridden using the override modifier. Wenn es sich um eine explizite außer Kraft Setzung handelt, die die Schnittstelle mit dem Member benennt, wird der Zugriffsmodifizierer ausgelassen.If it is an "explicit" override that names the interface containing the member, the access modifier is omitted.

Geschlossene Probleme: Muss der Zugriffsmodifizierer abgeglichen werden, wenn es sich um eine "implizite" außer Kraft Setzung handelt, die der Schnittstelle nicht entspricht?Closed Issue: If it is an "implicit" override that does not name the interface, does the access modifier have to match?

Entscheidung: Nur öffentliche Member können implizit überschrieben werden, und der Zugriff muss entsprechend erfolgen.Decision: Only public members may be implicitly overridden, and the access must match. Siehe https://github.com/dotnet/csharplang/blob/master/meetings/2017/LDM-2017-04-18.md#dim-implementing-a-non-public-interface-member-not-in-list.See https://github.com/dotnet/csharplang/blob/master/meetings/2017/LDM-2017-04-18.md#dim-implementing-a-non-public-interface-member-not-in-list.

Problem öffnen: Ist der Zugriffsmodifizierer für eine explizite außer Kraft Setzung erforderlich, optional oder ausgelassen, z. b. override void IB.M() {}?Open Issue: Is the access modifier required, optional, or omitted on an explicit override such as override void IB.M() {}?

Problem öffnen: Ist override erforderlich, optional oder bei einer expliziten außer Kraft setzung, z. b. void IB.M() {}, ausgelassen?Open Issue: Is override required, optional, or omitted on an explicit override such as void IB.M() {}?

Wie implementiert ein nicht öffentliches Schnittstellenmember in einer Klasse?How does one implement a non-public interface member in a class? Sie müssen möglicherweise explizit ausgeführt werden?Perhaps it must be done explicitly?

interface IA
{
    internal void MI();
    protected void MP();
}
class C : IA
{
    // are these implementations?
    internal void MI() {}
    protected void MP() {}
}

Geschlossene Probleme: Wie implementiert ein nicht öffentliches Schnittstellenmember in einer Klasse?Closed Issue: How does one implement a non-public interface member in a class?

Entscheidung: Nicht öffentliche Schnittstellenmember können nur explizit implementiert werden.Decision: You can only implement non-public interface members explicitly. Siehe https://github.com/dotnet/csharplang/blob/master/meetings/2017/LDM-2017-04-18.md#dim-implementing-a-non-public-interface-member-not-in-list.See https://github.com/dotnet/csharplang/blob/master/meetings/2017/LDM-2017-04-18.md#dim-implementing-a-non-public-interface-member-not-in-list.

Entscheidung: für Schnittstellenmember ist kein override Schlüsselwort zulässig.Decision: No override keyword permitted on interface members. https://github.com/dotnet/csharplang/blob/master/meetings/2018/LDM-2018-10-17.md#does-an-override-in-an-interface-introduce-a-new-member

Binäre Kompatibilität 2 (geschlossen)Binary Compatibility 2 (closed)

Beachten Sie den folgenden Code, in dem sich die einzelnen Typen in einer separaten Assembly befinden.Consider the following code in which each type is in a separate assembly

interface I1
{
    void M() { Impl1 }
}
interface I2 : I1
{
    override void M() { Impl2 }
}
interface I3 : I1
{
}
class C : I2, I3
{
}

Wir wissen, dass die Implementierung von I1.M in C I2.Mist.We understand that the implementation of I1.M in C is I2.M. Was geschieht, wenn die Assembly, die I3 enthält, wie folgt geändert und neu kompiliert wird.What if the assembly containing I3 is changed as follows and recompiled

interface I3 : I1
{
    override void M() { Impl3 }
}

C wird jedoch nicht neu kompiliert.but C is not recompiled. Was geschieht, wenn das Programm ausgeführt wird?What happens when the program is run? Ein Aufruf von (C as I1).M()An invocation of (C as I1).M()

  1. Führt I1.MRuns I1.M
  2. Führt I2.MRuns I2.M
  3. Führt I3.MRuns I3.M
  4. Entweder 2 oder 3, deterministischEither 2 or 3, deterministically
  5. Löst eine Art von Lauf Zeit Ausnahme aus.Throws some kind of runtime exception

Entscheidung: lösen Sie eine Ausnahme aus (5).Decision: Throw an exception (5). Siehe https://github.com/dotnet/csharplang/blob/master/meetings/2018/LDM-2018-10-17.md#issues-in-default-interface-methods.See https://github.com/dotnet/csharplang/blob/master/meetings/2018/LDM-2018-10-17.md#issues-in-default-interface-methods.

partial in der Schnittstelle zulassen?Permit partial in interface? geschlossen(closed)

Da Schnittstellen in ähnlicher Weise wie abstrakte Klassen verwendet werden können, kann es sinnvoll sein, Sie partialzu deklarieren.Given that interfaces may be used in ways analogous to the way abstract classes are used, it may be useful to declare them partial. Dies wäre besonders nützlich bei Generatoren.This would be particularly useful in the face of generators.

Angebot: Entfernen Sie die sprach Einschränkung, dass Schnittstellen und Member von Schnittstellen möglicherweise nicht als partialdeklariert werden.Proposal: Remove the language restriction that interfaces and members of interfaces may not be declared partial.

Entscheidung: Ja.Decision: Yes. Siehe https://github.com/dotnet/csharplang/blob/master/meetings/2018/LDM-2018-10-17.md#permit-partial-in-interface.See https://github.com/dotnet/csharplang/blob/master/meetings/2018/LDM-2018-10-17.md#permit-partial-in-interface.

Main in einer Schnittstelle?Main in an interface? geschlossen(closed)

Problem öffnen: Ist eine static Main Methode in einer Schnittstelle ein Kandidat für den Einstiegspunkt des Programms?Open Issue: Is a static Main method in an interface a candidate to be the program's entry point?

Entscheidung: Ja.Decision: Yes. Siehe https://github.com/dotnet/csharplang/blob/master/meetings/2018/LDM-2018-10-17.md#main-in-an-interface.See https://github.com/dotnet/csharplang/blob/master/meetings/2018/LDM-2018-10-17.md#main-in-an-interface.

Bestätigen, dass öffentliche, nicht virtuelle Methoden unterstützt werden sollen (geschlossen)Confirm intent to support public non-virtual methods (closed)

Können wir unsere Entscheidung bestätigen (oder umkehren), um nicht virtuelle öffentliche Methoden in einer Schnittstelle zuzulassen?Can we please confirm (or reverse) our decision to permit non-virtual public methods in an interface?

interface IA
{
    public sealed void M() { }
}

Semiclosed-Problem: (2017-04-18) Wir sind davon überzeugt, dass es nützlich sein wird, es wird jedoch zurückgegeben.Semi-Closed Issue: (2017-04-18) We think it is going to be useful, but will come back to it. Dabei handelt es sich um einen Block für das Muster des geistigen Modells.This is a mental model tripping block.

Entscheidung: Ja.Decision: Yes. https://login.microsoftonline.com/consumers/.https://github.com/dotnet/csharplang/blob/master/meetings/2018/LDM-2018-10-17.md#confirm-that-we-support-public-non-virtual-methods.

Führt ein override in einer Schnittstelle ein neues Mitglied ein?Does an override in an interface introduce a new member? geschlossen(closed)

Es gibt mehrere Möglichkeiten, um zu überprüfen, ob eine Überschreibungs Deklaration einen neuen Member einführt.There are a few ways to observe whether an override declaration introduces a new member or not.

interface IA
{
    void M(int x) { }
}
interface IB : IA
{
    override void M(int y) { }
}
interface IC : IB
{
    static void M2()
    {
        M(y: 3); // permitted?
    }
    override void IB.M(int z) { } // permitted? What does it override?
}

Problem öffnen: Führt eine Überschreibungs Deklaration in einer Schnittstelle einen neuen Member ein?Open Issue: Does an override declaration in an interface introduce a new member? geschlossen(closed)

In einer Klasse ist eine über schreibende Methode in gewisser Hinsicht "sichtbar".In a class, an overriding method is "visible" in some senses. Die Namen der Parameter haben beispielsweise Vorrang vor den Namen von Parametern in der überschriebenen Methode.For example, the names of its parameters take precedence over the names of parameters in the overridden method. Möglicherweise ist es möglich, dieses Verhalten in Schnittstellen zu duplizieren, da immer eine spezifischere außer Kraft Setzung vorliegt.It may be possible to duplicate that behavior in interfaces, as there is always a most specific override. Möchten Sie dieses Verhalten jedoch duplizieren?But do we want to duplicate that behavior?

Außerdem ist es möglich, eine Überschreibungs Methode außer Kraft zu setzen?Also, it is possible to "override" an override method? Fraglich[Moot]

Entscheidung: für Schnittstellenmember ist kein override Schlüsselwort zulässig.Decision: No override keyword permitted on interface members. https://login.microsoftonline.com/consumers/.https://github.com/dotnet/csharplang/blob/master/meetings/2018/LDM-2018-10-17.md#does-an-override-in-an-interface-introduce-a-new-member.

Eigenschaften mit einem privaten Accessor (geschlossen)Properties with a private accessor (closed)

Wir sagen, dass private Member nicht virtuell sind und die Kombination aus Virtual und private nicht zulässig ist.We say that private members are not virtual, and the combination of virtual and private is disallowed. Aber wie sieht es mit einer Eigenschaft mit einem privaten Accessor aus?But what about a property with a private accessor?

interface IA
{
    public virtual int P
    {
        get => 3;
        private set => { }
    }
}

Ist dies zulässig?Is this allowed? virtual der set Accessor oder nicht?Is the set accessor here virtual or not? Kann sie überschrieben werden, wo Sie zugänglich ist?Can it be overridden where it is accessible? Implementiert Folgendes implizit nur den get Accessor?Does the following implicitly implement only the get accessor?

class C : IA
{
    public int P
    {
        get => 4;
        set { }
    }
}

Der folgende Fehler ist vermutlich ein Fehler, weil IA vorliegt. P. Set ist nicht virtuell und auch weil nicht darauf zugegriffen werden kann?Is the following presumably an error because IA.P.set isn't virtual and also because it isn't accessible?

class C : IA
{
    int IA.P
    {
        get => 4;
        set { }
    }
}

Entscheidung: das erste Beispiel ist gültig, während das letzte nicht.Decision: The first example looks valid, while the last does not. Dies wird analog zur Funktionsweise in C#gelöst.This is resolved analogously to how it already works in C#. https://github.com/dotnet/csharplang/blob/master/meetings/2018/LDM-2018-10-17.md#properties-with-a-private-accessor

Basis Schnittstellen Aufrufe, Round 2 (geschlossen)Base Interface Invocations, round 2 (closed)

Unsere vorherige "Lösung" zur Behandlung von grundlegenden aufrufen bietet keine ausreichende Ausdruckskraft.Our previous "resolution" to how to handle base invocations doesn't actually provide sufficient expressiveness. Es stellt sich heraus, C# dass Sie in und der CLR im Gegensatz zu Java sowohl die-Schnittstelle, die die Methoden Deklaration enthält, als auch den Speicherort der Implementierung angeben müssen, die Sie aufrufen möchten.It turns out that in C# and the CLR, unlike Java, you need to specify both the interface containing the method declaration and the location of the implementation you want to invoke.

Ich schlage die folgende Syntax für Basis Aufrufe in Schnittstellen vor.I propose the following syntax for base calls in interfaces. Ich bin nicht in der Liebe, aber es wird veranschaulicht, welche Syntax in der Lage sein muss, folgendes auszudrücken:I’m not in love with it, but it illustrates what any syntax must be able to express:

interface I1 { void M(); }
interface I2 { void M(); }
interface I3 : I1, I2 { void I1.M() { } void I2.M() { } }
interface I4 : I1, I2 { void I1.M() { } void I2.M() { } }
interface I5 : I3, I4
{
    void I1.M()
    {
        base<I3>(I1).M(); // calls I3's implementation of I1.M
        base<I4>(I1).M(); // calls I4's implementation of I1.M
    }
    void I2.M()
    {
        base<I3>(I2).M(); // calls I3's implementation of I2.M
        base<I4>(I2).M(); // calls I4's implementation of I2.M
    }
}

Wenn keine Mehrdeutigkeit vorliegt, können Sie Sie einfacher schreiben.If there is no ambiguity, you can write it more simply

interface I1 { void M(); }
interface I3 : I1 { void I1.M() { } }
interface I4 : I1 { void I1.M() { } }
interface I5 : I3, I4
{
    void I1.M()
    {
        base<I3>.M(); // calls I3's implementation of I1.M
        base<I4>.M(); // calls I4's implementation of I1.M
    }
}

OderOr

interface I1 { void M(); }
interface I2 { void M(); }
interface I3 : I1, I2 { void I1.M() { } void I2.M() { } }
interface I5 : I3
{
    void I1.M()
    {
        base(I1).M(); // calls I3's implementation of I1.M
    }
    void I2.M()
    {
        base(I2).M(); // calls I3's implementation of I2.M
    }
}

OderOr

interface I1 { void M(); }
interface I3 : I1 { void I1.M() { } }
interface I5 : I3
{
    void I1.M()
    {
        base.M(); // calls I3's implementation of I1.M
    }
}

Entscheidung: entscheiden Sie sich für base(N.I1<T>).M(s), und wenn wir eine Aufruf Bindung haben, können Sie später möglicherweise Probleme finden.Decision: Decided on base(N.I1<T>).M(s), conceding that if we have an invocation binding there may be problem here later on. https://github.com/dotnet/csharplang/blob/master/meetings/2018/LDM-2018-11-14.md#default-interface-implementations

Warnung für die Struktur, die die Standardmethode nicht implementiert?Warning for struct not implementing default method? geschlossen(closed)

@vancem bestätigt, dass wir ernsthaft eine Warnung erstellen sollten, wenn eine Werttyp Deklaration eine Schnittstellen Methode nicht außer Kraft setzt, auch wenn Sie eine Implementierung dieser Methode von einer Schnittstelle erben würde.@vancem asserts that we should seriously consider producing a warning if a value type declaration fails to override some interface method, even if it would inherit an implementation of that method from an interface. Da dies zum Boxing und zum untergraben von eingeschränkten aufrufen bewirkt.Because it causes boxing and undermines constrained calls.

Entscheidung: Dies scheint etwas, das für einen Analyzer besser geeignet ist.Decision: This seems like something more suited for an analyzer. Es scheint auch, dass diese Warnung nicht mehr angezeigt wird, da Sie auch dann ausgelöst würde, wenn die Standardschnittstellen Methode niemals aufgerufen wird und nie Boxing auftritt.It also seems like this warning could be noisy, since it would fire even if the default interface method is never called and no boxing will ever occur. https://github.com/dotnet/csharplang/blob/master/meetings/2018/LDM-2018-10-17.md#warning-for-struct-not-implementing-default-method

Statische Schnittstellen Konstruktoren (geschlossen)Interface static constructors (closed)

Wann werden statische Konstruktoren für die Schnittstelle ausgeführt?When are interface static constructors run? Der aktuelle CLI-Entwurf schlägt vor, dass er auftritt, wenn auf die erste statische Methode oder das erste Feld zugegriffen wird.The current CLI draft proposes that it occurs when the first static method or field is accessed. Wenn keines davon vorhanden ist, wird es möglicherweise nie ausgeführt?If there are neither of those then it might never be run??

[2018-10-09 das CLR-Team schlägt vor, was wir für Werttypen tun (cctor Check on Access to each instance method)][2018-10-09 The CLR team proposes "Going to mirror what we do for valuetypes (cctor check on access to each instance method)"]

Entscheidung: statische Konstruktoren werden auch für den Eintrag in Instanzmethoden ausgeführt, wenn der statische Konstruktor nicht beforefieldinitwurde. in diesem Fall werden statische Konstruktoren vor dem Zugriff auf das erste statische Feld ausgeführt.Decision: Static constructors are also run on entry to instance methods, if the static constructor was not beforefieldinit, in which case static constructors are run before access to the first static field. https://github.com/dotnet/csharplang/blob/master/meetings/2018/LDM-2018-10-17.md#when-are-interface-static-constructors-run

Treffen von BesprechungenDesign meetings

2017-03-08 LDM Meeting Notes 2017-03-21 LDM Meeting Notes 2017-03-23 Meeting "CLR Behavior for Default Interface Methods" 2017-04-05 LDM Meeting Notes 2017-04-11 LDM Meeting Notes 2017-04-18 LDM Meeting Notes 2017-04-19 LDM Meeting Notes 2017-05-17 LDM Meeting Notes 2017-05-31 LDM Meeting Notes 2017-06-14 LDM Besprechungs Hinweise 2018-10-17 LDM Meeting Notes 2018-11-14 LDM Meeting Notes2017-03-08 LDM Meeting Notes 2017-03-21 LDM Meeting Notes 2017-03-23 meeting "CLR Behavior for Default Interface Methods" 2017-04-05 LDM Meeting Notes 2017-04-11 LDM Meeting Notes 2017-04-18 LDM Meeting Notes 2017-04-19 LDM Meeting Notes 2017-05-17 LDM Meeting Notes 2017-05-31 LDM Meeting Notes 2017-06-14 LDM Meeting Notes 2018-10-17 LDM Meeting Notes 2018-11-14 LDM Meeting Notes