SchnittstellenInterfaces

Eine Schnittstelle definiert einen Vertrag.An interface defines a contract. Eine Klasse oder Struktur, die eine Schnittstelle implementiert, muss ihren Vertrag einhalten.A class or struct that implements an interface must adhere to its contract. Eine Schnittstelle kann von mehreren Basis Schnittstellen erben, und eine Klasse oder Struktur kann mehrere Schnittstellen implementieren.An interface may inherit from multiple base interfaces, and a class or struct may implement multiple interfaces.

Schnittstellen können Methoden, Eigenschaften, Ereignisse und Indexer enthalten.Interfaces can contain methods, properties, events, and indexers. Die Schnittstelle selbst stellt keine Implementierungen für die Member bereit, die Sie definiert.The interface itself does not provide implementations for the members that it defines. Die-Schnittstelle gibt lediglich die Member an, die von Klassen oder Strukturen bereitgestellt werden müssen, die die-Schnittstelle implementieren.The interface merely specifies the members that must be supplied by classes or structs that implement the interface.

Interface declarations (Schnittstellendeklarationen)Interface declarations

Ein interface_declaration ist ein type_declaration (Typdeklarationen), der einen neuen Schnittstellentyp deklariert.An interface_declaration is a type_declaration (Type declarations) that declares a new interface type.

interface_declaration
    : attributes? interface_modifier* 'partial'? 'interface'
      identifier variant_type_parameter_list? interface_base?
      type_parameter_constraints_clause* interface_body ';'?
    ;

Ein interface_declaration besteht aus einem optionalen Satz von Attributen (Attributen), gefolgt von einer optionalen Gruppe von interface_modifier s (Schnittstellen Modifizierern), gefolgt von einem partial optionalen-Modifizierer, gefolgt vom-Schlüsselwort interface und einem Bezeichner , der die-Schnittstelle benennt, gefolgt von einer optionalen variant_type_parameter_list -Spezifikation (Variant-Typparameter Listen), gefolgt von einer optionalen interface_base Spezifikation (Basis Schnittstellen), gefolgt von einer optionalen type_parameter_constraints_clause s-Spezifikation (Typparameter Einschränkungen), gefolgt von einer interface_body (Schnittstellen Text), optional gefolgt von einem semiAn interface_declaration consists of an optional set of attributes (Attributes), followed by an optional set of interface_modifier s (Interface modifiers), followed by an optional partial modifier, followed by the keyword interface and an identifier that names the interface, followed by an optional variant_type_parameter_list specification (Variant type parameter lists), followed by an optional interface_base specification (Base interfaces), followed by an optional type_parameter_constraints_clause s specification (Type parameter constraints), followed by an interface_body (Interface body), optionally followed by a semicolon.

SchnittstellenmodifiziererInterface modifiers

Eine interface_declaration kann optional eine Sequenz von Schnittstellen Modifizierer einschließen:An interface_declaration may optionally include a sequence of interface modifiers:

interface_modifier
    : 'new'
    | 'public'
    | 'protected'
    | 'internal'
    | 'private'
    | interface_modifier_unsafe
    ;

Es ist ein Kompilierzeitfehler, damit derselbe Modifizierer mehrmals in einer Schnittstellen Deklaration angezeigt wird.It is a compile-time error for the same modifier to appear multiple times in an interface declaration.

Der- new Modifizierer ist nur für Schnittstellen zulässig, die innerhalb einer Klasse definiert sind.The new modifier is only permitted on interfaces defined within a class. Er gibt an, dass die Schnittstelle einen geerbten Member mit demselben Namen verbirgt, wie im neuen Modifiziererbeschrieben.It specifies that the interface hides an inherited member by the same name, as described in The new modifier.

Die public protected internal private Modifizierer,, und Steuern den Zugriff auf die-Schnittstelle.The public, protected, internal, and private modifiers control the accessibility of the interface. Abhängig vom Kontext, in dem die Schnittstellen Deklaration auftritt, dürfen nur einige dieser Modifizierer zulässig sein (alsBarrierefreiheit deklariert).Depending on the context in which the interface declaration occurs, only some of these modifiers may be permitted (Declared accessibility).

Partieller ModifiziererPartial modifier

Der- partial Modifizierer gibt an, dass dieser interface_declaration eine partielle Typdeklaration ist.The partial modifier indicates that this interface_declaration is a partial type declaration. Mehrere partielle Schnittstellen Deklarationen mit demselben Namen innerhalb eines einschließenden Namespace oder einer Typdeklaration kombinieren eine Schnittstellen Deklaration, die den in partiellen Typenangegebenen Regeln folgt.Multiple partial interface declarations with the same name within an enclosing namespace or type declaration combine to form one interface declaration, following the rules specified in Partial types.

Parameterlisten für Variant-TypenVariant type parameter lists

Variant-Typparameter Listen können nur für Schnittstellen-und Delegattypen auftreten.Variant type parameter lists can only occur on interface and delegate types. Der Unterschied zwischen normaler type_parameter_list s ist der optionale variance_annotation für jeden Typparameter.The difference from ordinary type_parameter_list s is the optional variance_annotation on each type parameter.

variant_type_parameter_list
    : '<' variant_type_parameters '>'
    ;

variant_type_parameters
    : attributes? variance_annotation? type_parameter
    | variant_type_parameters ',' attributes? variance_annotation? type_parameter
    ;

variance_annotation
    : 'in'
    | 'out'
    ;

Wenn die Varianz Anmerkung ist out , wird der Typparameter als *kovariant _ bezeichnet.If the variance annotation is out, the type parameter is said to be *covariant _. Wenn die Varianz Anmerkung ist in , wird der Typparameter als kontra Variant bezeichnet.If the variance annotation is in, the type parameter is said to be contravariant. Wenn keine Varianz Anmerkung vorhanden ist, wird der Typparameter als _ invariante * bezeichnet.If there is no variance annotation, the type parameter is said to be _*invariant**.

Im BeispielIn the example

interface C<out X, in Y, Z> 
{
  X M(Y y);
  Z P { get; set; }
}

X ist kovariant, Y ist kontra Variant und Z ist unveränderlich.X is covariant, Y is contravariant and Z is invariant.

Varianz SicherheitVariance safety

Das Vorkommen von Varianz Anmerkungen in der Typparameter Liste eines Typs schränkt die stellen ein, an denen Typen innerhalb der Typdeklaration vorkommen können.The occurrence of variance annotations in the type parameter list of a type restricts the places where types can occur within the type declaration.

Ein Typ T ist " Output-unsicher ", wenn einer der folgenden Punkte enthält:A type T is output-unsafe if one of the following holds:

  • T ist ein kontra varianter Typparameter.T is a contravariant type parameter
  • T ist ein Arraytyp mit einem Ausgabe unsicheren Elementtyp.T is an array type with an output-unsafe element type
  • T ist eine Schnittstelle oder ein Delegattyp, der S<A1,...,Ak> aus einem generischen Typ erstellt wird, S<X1,...,Xk> wobei mindestens einer der Ai folgenden Punkte enthält:T is an interface or delegate type S<A1,...,Ak> constructed from a generic type S<X1,...,Xk> where for at least one Ai one of the following holds:
    • Xi ist kovariant oder invariante und Ai ist Ausgabe unsicher.Xi is covariant or invariant and Ai is output-unsafe.
    • Xi ist kontra Variant oder invariante und Ai ist Eingabe sicher.Xi is contravariant or invariant and Ai is input-safe.

Ein Typ T ist Eingabe unsicher , wenn eine der folgenden Punkte Folgendes enthält:A type T is input-unsafe if one of the following holds:

  • T ist ein kovariant-Typparameter.T is a covariant type parameter
  • T ist ein Arraytyp mit einem Eingabe unsicheren Elementtyp.T is an array type with an input-unsafe element type
  • T ist eine Schnittstelle oder ein Delegattyp, der S<A1,...,Ak> aus einem generischen Typ erstellt wird, S<X1,...,Xk> wobei mindestens einer der Ai folgenden Punkte enthält:T is an interface or delegate type S<A1,...,Ak> constructed from a generic type S<X1,...,Xk> where for at least one Ai one of the following holds:
    • Xi ist kovariant oder invariante und Ai ist Eingabe unsicher.Xi is covariant or invariant and Ai is input-unsafe.
    • Xi ist kontra Variant oder invariante und Ai ist Ausgabe unsicher.Xi is contravariant or invariant and Ai is output-unsafe.

Intuitiv ist ein durch die Ausgabe unsicherer Typ in einer Ausgabe Position unzulässig, und ein Eingabe unsicherer Typ ist an einer Eingabe Position unzulässig.Intuitively, an output-unsafe type is prohibited in an output position, and an input-unsafe type is prohibited in an input position.

Ein Typ ist *Output-Safe _, wenn er nicht für die Ausgabe unsicher ist, und _ *Input-Safe**, wenn er nicht Eingabe unsicher ist.A type is output-safe _ if it is not output-unsafe, and _ input-safe if it is not input-unsafe.

Varianz KonvertierungVariance conversion

Der Zweck von Varianz Anmerkungen besteht darin, für die Schnittstellen-und Delegattypen eine genauere (aber dennoch typsichere) Konvertierung bereitzustellen.The purpose of variance annotations is to provide for more lenient (but still type safe) conversions to interface and delegate types. Zu diesem Zweck verwenden die Definitionen impliziter (impliziter Konvertierungen) und expliziter Konvertierungen (explizite Konvertierungen) das Konzept der Varianz Konvertierungen, das wie folgt definiert wird:To this end the definitions of implicit (Implicit conversions) and explicit conversions (Explicit conversions) make use of the notion of variance-convertibility, which is defined as follows:

Ein Typ T<A1,...,An> ist Varianz konvertierbar in einen T<B1,...,Bn> Typ T , wenn entweder eine Schnittstelle oder ein Delegattyp ist, der mit den Varianten Typparametern deklariert T<X1,...,Xn> wurde, und für jeden Variant-Typparameter, Xi den eine der folgenden Werte enthält:A type T<A1,...,An> is variance-convertible to a type T<B1,...,Bn> if T is either an interface or a delegate type declared with the variant type parameters T<X1,...,Xn>, and for each variant type parameter Xi one of the following holds:

  • Xiist kovariant, und ein impliziter Verweis oder eine Identitäts Konvertierung ist von in vorhanden. Ai``BiXi is covariant and an implicit reference or identity conversion exists from Ai to Bi
  • Xi ist kontra Variant, und ein impliziter Verweis oder eine Identitäts Konvertierung ist von Bi zu AiXi is contravariant and an implicit reference or identity conversion exists from Bi to Ai
  • Xi ist invariante, und eine Identitäts Konvertierung ist von Ai zu BiXi is invariant and an identity conversion exists from Ai to Bi

Basis SchnittstellenBase interfaces

Eine Schnittstelle kann von NULL oder mehr Schnittstellentypen erben, die als explizite Basis Schnittstellen der Schnittstelle bezeichnet werden.An interface can inherit from zero or more interface types, which are called the explicit base interfaces of the interface. Wenn eine Schnittstelle über eine oder mehrere explizite Basis Schnittstellen verfügt, folgt in der Deklaration dieser Schnittstelle der Schnittstellen Bezeichner einen Doppelpunkt und eine durch Kommas getrennte Liste von Basis Schnittstellentypen.When an interface has one or more explicit base interfaces, then in the declaration of that interface, the interface identifier is followed by a colon and a comma separated list of base interface types.

interface_base
    : ':' interface_type_list
    ;

Für einen konstruierten Schnittstellentyp werden die expliziten Basis Schnittstellen gebildet, indem die expliziten Basis Schnittstellen Deklarationen in der generischen Typdeklaration übernommen und für jede type_parameter in der Basis Schnittstellen Deklaration ersetzt werden, die entsprechende type_argument des konstruierten Typs.For a constructed interface type, the explicit base interfaces are formed by taking the explicit base interface declarations on the generic type declaration, and substituting, for each type_parameter in the base interface declaration, the corresponding type_argument of the constructed type.

Die expliziten Basis Schnittstellen einer Schnittstelle müssen mindestens so zugänglich sein wie die Schnittstelle selbst (Barrierefreiheits Einschränkungen).The explicit base interfaces of an interface must be at least as accessible as the interface itself (Accessibility constraints). Beispielsweise ist es ein Kompilierzeitfehler, eine- private oder- internal Schnittstelle im interface_base einer- public Schnittstelle anzugeben.For example, it is a compile-time error to specify a private or internal interface in the interface_base of a public interface.

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. Eine Schnittstelle erbt alle Member ihrer Basis Schnittstellen.An interface inherits all members of its base interfaces. Im BeispielIn the example

interface IControl
{
    void Paint();
}

interface ITextBox: IControl
{
    void SetText(string text);
}

interface IListBox: IControl
{
    void SetItems(string[] items);
}

interface IComboBox: ITextBox, IListBox {}

die Basis Schnittstellen von IComboBox sind IControl , ITextBox und IListBox .the base interfaces of IComboBox are IControl, ITextBox, and IListBox.

Mit anderen Worten, die IComboBox obige Schnittstelle erbt Member SetText und SetItems sowie Paint .In other words, the IComboBox interface above inherits members SetText and SetItems as well as Paint.

Jede Basisschnittstelle einer Schnittstelle muss Ausgabe sicher sein (Varianz Sicherheit).Every base interface of an interface must be output-safe (Variance safety). Eine Klasse oder Struktur, die eine Schnittstelle implementiert, implementiert auch implizit alle Basis Schnittstellen der Schnittstelle.A class or struct that implements an interface also implicitly implements all of the interface's base interfaces.

Schnittstellen TextInterface body

Der interface_body einer Schnittstelle definiert die Member der Schnittstelle.The interface_body of an interface defines the members of the interface.

interface_body
    : '{' interface_member_declaration* '}'
    ;

Interface members (Schnittstellenmember)Interface members

Die Member einer Schnittstelle sind die Member, die von den Basis Schnittstellen und den Membern geerbt werden, die von der Schnittstelle selbst deklariert werden.The members of an interface are the members inherited from the base interfaces and the members declared by the interface itself.

interface_member_declaration
    : interface_method_declaration
    | interface_property_declaration
    | interface_event_declaration
    | interface_indexer_declaration
    ;

Eine Schnittstellen Deklaration kann NULL oder mehr Member deklarieren.An interface declaration may declare zero or more members. Die Member einer Schnittstelle müssen Methoden, Eigenschaften, Ereignisse oder Indexer sein.The members of an interface must be methods, properties, events, or indexers. Eine Schnittstelle kann keine Konstanten, Felder, Operatoren, Instanzkonstruktoren, Dekonstruktoren oder Typen enthalten, und eine Schnittstelle kann keine statischen Member beliebiger Art enthalten.An interface cannot contain constants, fields, operators, instance constructors, destructors, or types, nor can an interface contain static members of any kind.

Alle Schnittstellenmember haben implizit öffentlichen Zugriff.All interface members implicitly have public access. Es handelt sich um einen Kompilierzeitfehler für Schnittstellenmember-Deklarationen, um beliebige Modifizierer einzuschließenIt is a compile-time error for interface member declarations to include any modifiers. Insbesondere können Schnittstellenmember nicht mit den modifizierermembern abstract ,,,,,, oder deklariert werden public protected internal private virtual override static .In particular, interfaces members cannot be declared with the modifiers abstract, public, protected, internal, private, virtual, override, or static.

Das BeispielThe example

public delegate void StringListEvent(IStringList sender);

public interface IStringList
{
    void Add(string s);
    int Count { get; }
    event StringListEvent Changed;
    string this[int index] { get; set; }
}

deklariert eine Schnittstelle, die eine der möglichen Arten von Membern enthält: eine Methode, eine Eigenschaft, ein Ereignis und einen Indexer.declares an interface that contains one each of the possible kinds of members: A method, a property, an event, and an indexer.

Ein interface_declaration erstellt einen neuen Deklarations Raum (Deklarationen), und die interface_member_declaration s, die sofort im interface_declaration enthalten sind, stellen neue Member in diesen Deklarations Bereich ein.An interface_declaration creates a new declaration space (Declarations), and the interface_member_declaration s immediately contained by the interface_declaration introduce new members into this declaration space. Die folgenden Regeln gelten für interface_member_declaration s:The following rules apply to interface_member_declaration s:

  • Der Name einer Methode muss sich von den Namen aller Eigenschaften und Ereignisse unterscheiden, die in derselben Schnittstelle deklariert werden.The name of a method must differ from the names of all properties and events declared in the same interface. Außerdem müssen sich die Signatur (Signaturen und überladen) einer Methode von den Signaturen aller anderen Methoden unterscheiden, die in derselben Schnittstelle deklariert sind, und zwei Methoden, die in der gleichen Schnittstelle deklariert werden, verfügen möglicherweise nicht über Signaturen, die sich ausschließlich durch und unterscheiden ref out .In addition, the signature (Signatures and overloading) of a method must differ from the signatures of all other methods declared in the same interface, and two methods declared in the same interface may not have signatures that differ solely by ref and out.
  • Der Name einer Eigenschaft oder eines Ereignisses muss sich von den Namen aller anderen Member unterscheiden, die in derselben Schnittstelle deklariert werden.The name of a property or event must differ from the names of all other members declared in the same interface.
  • Die Signatur eines Indexers muss sich von den Signaturen aller anderen in derselben Schnittstelle deklarierten Indexer unterscheiden.The signature of an indexer must differ from the signatures of all other indexers declared in the same interface.

Die geerbten Member einer Schnittstelle sind nicht Teil des Deklarations Raums der Schnittstelle.The inherited members of an interface are specifically not part of the declaration space of the interface. Daher kann eine Schnittstelle einen Member mit demselben Namen oder derselben Signatur wie ein geerbte Member deklarieren.Thus, an interface is allowed to declare a member with the same name or signature as an inherited member. Wenn dies auftritt, wird der Member der abgeleiteten Schnittstelle zum Ausblenden des basisschnittstellenmembers bezeichnet.When this occurs, the derived interface member is said to hide the base interface member. Das Ausblenden eines geerbten Members wird nicht als Fehler betrachtet, bewirkt jedoch, dass der Compiler eine Warnung ausgibt.Hiding an inherited member is not considered an error, but it does cause the compiler to issue a warning. Um die Warnung zu unterdrücken, muss die Deklaration des abgeleiteten Schnittstellenmembers einen new Modifizierer enthalten, um anzugeben, dass der abgeleitete Member den Basismember ausblenden soll.To suppress the warning, the declaration of the derived interface member must include a new modifier to indicate that the derived member is intended to hide the base member. Dieses Thema wird unter Ausblenden durch Vererbungausführlicher erläutert.This topic is discussed further in Hiding through inheritance.

Wenn ein new Modifizierer in einer Deklaration enthalten ist, die einen geerbten Member nicht ausgeblendet hat, wird eine Warnung für diesen Effekt ausgegeben.If a new modifier is included in a declaration that doesn't hide an inherited member, a warning is issued to that effect. Diese Warnung wird durch Entfernen des- new Modifizierers unterdrückt.This warning is suppressed by removing the new modifier.

Beachten Sie, dass die Member in der Klasse object nicht, streng genommen Member einer beliebigen Schnittstelle (Schnittstellenmember) sind.Note that the members in class object are not, strictly speaking, members of any interface (Interface members). Allerdings sind die Member in der Klasse object über die Element Suche in einem beliebigen Schnittstellentyp (Member-Suche) verfügbar.However, the members in class object are available via member lookup in any interface type (Member lookup).

Schnittstellen MethodenInterface methods

Schnittstellen Methoden werden mithilfe von interface_method_declaration s deklariert:Interface methods are declared using interface_method_declaration s:

interface_method_declaration
    : attributes? 'new'? return_type identifier type_parameter_list
      '(' formal_parameter_list? ')' type_parameter_constraints_clause* ';'
    ;

Die Attribute, return_type, Bezeichner und formal_parameter_list einer Schnittstellen Methoden Deklaration haben dieselbe Bedeutung wie die einer Methoden Deklaration in einer Klasse (Methoden).The attributes, return_type, identifier, and formal_parameter_list of an interface method declaration have the same meaning as those of a method declaration in a class (Methods). Eine Schnittstellen Methoden Deklaration darf keinen Methoden Text angeben, und die Deklaration endet daher immer mit einem Semikolon.An interface method declaration is not permitted to specify a method body, and the declaration therefore always ends with a semicolon.

Jeder formale Parametertyp einer Schnittstellen Methode muss Eingabe sicher (Varianz Sicherheit) sein, und der void Rückgabetyp muss entweder oder Output-sicher sein.Each formal parameter type of an interface method must be input-safe (Variance safety), and the return type must be either void or output-safe. Außerdem müssen jede Klassentyp Einschränkung, schnittstellentypeinschränkung und Typparameter Einschränkung für jeden Typparameter der Methode Eingabe sicher sein.Furthermore, each class type constraint, interface type constraint and type parameter constraint on any type parameter of the method must be input-safe.

Diese Regeln stellen sicher, dass jede kovariante oder Kontra Variante Verwendung der Schnittstelle typsicher bleibt.These rules ensure that any covariant or contravariant usage of the interface remains type-safe. Beispiel:For example,

interface I<out T> { void M<U>() where U : T; }

ist unzulässig, da die Verwendung von T als Typparameter Einschränkung für U nicht Eingabe sicher ist.is illegal because the usage of T as a type parameter constraint on U is not input-safe.

Wenn diese Einschränkung nicht vorhanden ist, kann die Typsicherheit folgendermaßen verletzt werden:Were this restriction not in place it would be possible to violate type safety in the following manner:

class B {}
class D : B{}
class E : B {}
class C : I<D> { public void M<U>() {...} }
...
I<B> b = new C();
b.M<E>();

Dabei handelt es sich um einen-Rückruf C.M<E> .This is actually a call to C.M<E>. Dieser-Rückruf erfordert jedoch, dass E von abgeleitet D ist, sodass die Typsicherheit hier verletzt wird.But that call requires that E derive from D, so type safety would be violated here.

SchnittstelleneigenschaftenInterface properties

Schnittstelleneigenschaften werden mit interface_property_declaration s deklariert:Interface properties are declared using interface_property_declaration s:

interface_property_declaration
    : attributes? 'new'? type identifier '{' interface_accessors '}'
    ;

interface_accessors
    : attributes? 'get' ';'
    | attributes? 'set' ';'
    | attributes? 'get' ';' attributes? 'set' ';'
    | attributes? 'set' ';' attributes? 'get' ';'
    ;

Die Attribute, der Typ und der Bezeichner einer Schnittstellen Eigenschafts Deklaration haben dieselbe Bedeutung wie die einer Eigenschafts Deklaration in einer Klasse (Eigenschaften).The attributes, type, and identifier of an interface property declaration have the same meaning as those of a property declaration in a class (Properties).

Die Accessoren einer Schnittstelleneigenschaften Deklaration entsprechen den Accessoren einer Klassen Eigenschafts Deklaration (Accessoren), mit dem Unterschied, dass der Accessortext immer ein Semikolon sein muss.The accessors of an interface property declaration correspond to the accessors of a class property declaration (Accessors), except that the accessor body must always be a semicolon. Daher geben die Accessoren einfach an, ob die Eigenschaft Lese-/Schreibzugriff, schreibgeschützt oder schreibgeschützt ist.Thus, the accessors simply indicate whether the property is read-write, read-only, or write-only.

Der Typ einer Schnittstellen Eigenschaft muss bei einem get-Accessor Ausgabe sicher sein und muss eingegeben werden können, wenn ein Set-Accessor vorhanden ist.The type of an interface property must be output-safe if there is a get accessor, and must be input-safe if there is a set accessor.

Schnittstellen EreignisseInterface events

Schnittstellen Ereignisse werden mithilfe von interface_event_declaration s deklariert:Interface events are declared using interface_event_declaration s:

interface_event_declaration
    : attributes? 'new'? 'event' type identifier ';'
    ;

Die Attribute, der Typ und der Bezeichner einer Schnittstellen-Ereignis Deklaration haben dieselbe Bedeutung wie die einer Ereignis Deklaration in einer Klasse (Ereignisse).The attributes, type, and identifier of an interface event declaration have the same meaning as those of an event declaration in a class (Events).

Der Typ eines Schnittstellen Ereignisses muss Eingabe sicher sein.The type of an interface event must be input-safe.

Schnittstellen IndexerInterface indexers

Schnittstellenindexer werden mithilfe von interface_indexer_declaration s deklariert:Interface indexers are declared using interface_indexer_declaration s:

interface_indexer_declaration
    : attributes? 'new'? type 'this' '[' formal_parameter_list ']' '{' interface_accessors '}'
    ;

Die Attribute, der Typ und formal_parameter_list einer Schnittstellenindexer-Deklaration haben dieselbe Bedeutung wie die einer Indexer-Deklaration in einer Klasse (Indexer).The attributes, type, and formal_parameter_list of an interface indexer declaration have the same meaning as those of an indexer declaration in a class (Indexers).

Die Accessoren einer Schnittstellenindexer-Deklaration entsprechen den Accessoren einer Klassenindexer-Deklaration (Indexer), mit dem Unterschied, dass der Accessor-Text immer ein Semikolon sein muss.The accessors of an interface indexer declaration correspond to the accessors of a class indexer declaration (Indexers), except that the accessor body must always be a semicolon. Daher geben die Accessoren einfach an, ob der Indexer Lese-/Schreibzugriff, schreibgeschützt oder schreibgeschützt ist.Thus, the accessors simply indicate whether the indexer is read-write, read-only, or write-only.

Alle formalen Parametertypen eines schnittstellenindexers müssen Eingabe sicher sein.All the formal parameter types of an interface indexer must be input-safe . Außerdem out müssen alle oder ref formalen Parametertypen ebenfalls Ausgabe sicher sein.In addition, any out or ref formal parameter types must also be output-safe. Beachten Sie, dass auch out Parameter aufgrund einer Einschränkung der zugrunde liegenden Ausführungsplattform Eingabe sicher sein müssen.Note that even out parameters are required to be input-safe, due to a limitation of the underlying execution platform.

Der Typ eines schnittstellenindexers muss bei einem get-Accessor Ausgabe sicher sein und muss eingegeben werden können, wenn ein Set-Accessor vorhanden ist.The type of an interface indexer must be output-safe if there is a get accessor, and must be input-safe if there is a set accessor.

Zugriff auf SchnittstellenmemberInterface member access

Der Zugriff auf Schnittstellenmember erfolgt über Member Access (Member Access) und Indexer Access (Indexer Access)-Ausdrücke der Form I.M und I[A] , wobei I ein Schnittstellentyp ist, M eine Methode, eine Eigenschaft oder ein Ereignis dieses Schnittstellen Typs ist und A eine Indexer-Argumentliste ist.Interface members are accessed through member access (Member access) and indexer access (Indexer access) expressions of the form I.M and I[A], where I is an interface type, M is a method, property, or event of that interface type, and A is an indexer argument list.

Bei Schnittstellen, die nur eine einzelne Vererbung haben (jede Schnittstelle in der Vererbungs Kette weist genau null oder eine direkte Basisschnittstelle auf), die Auswirkungen der Regeln für die Member-Suche (ElementSuche), Methodenaufrufe (Methodenaufrufe) und Indexer-Zugriff (Indexer-Zugriff) sind identisch mit den Regeln für Klassen und Strukturen: mehr abgeleitete Member Blenden weniger abgeleitete Member mit demselben Namen oder derselben Signatur aus.For interfaces that are strictly single-inheritance (each interface in the inheritance chain has exactly zero or one direct base interface), the effects of the member lookup (Member lookup), method invocation (Method invocations), and indexer access (Indexer access) rules are exactly the same as for classes and structs: More derived members hide less derived members with the same name or signature. Allerdings können Mehrdeutigkeiten bei Schnittstellen mit mehreren Vererbungen auftreten, wenn zwei oder mehr nicht verknüpfte Basis Schnittstellen Member mit demselben Namen oder derselben Signatur deklarieren.However, for multiple-inheritance interfaces, ambiguities can occur when two or more unrelated base interfaces declare members with the same name or signature. In diesem Abschnitt werden einige Beispiele für derartige Situationen gezeigt.This section shows several examples of such situations. In allen Fällen können explizite Umwandlungen verwendet werden, um die Mehrdeutigkeiten aufzulösen.In all cases, explicit casts can be used to resolve the ambiguities.

Im BeispielIn the example

interface IList
{
    int Count { get; set; }
}

interface ICounter
{
    void Count(int i);
}

interface IListCounter: IList, ICounter {}

class C
{
    void Test(IListCounter x) {
        x.Count(1);                  // Error
        x.Count = 1;                 // Error
        ((IList)x).Count = 1;        // Ok, invokes IList.Count.set
        ((ICounter)x).Count(1);      // Ok, invokes ICounter.Count
    }
}

die ersten beiden-Anweisungen verursachen Kompilierzeitfehler, da die Element Suche (Member Suche) von Count in IListCounter mehrdeutig ist.the first two statements cause compile-time errors because the member lookup (Member lookup) of Count in IListCounter is ambiguous. Wie im Beispiel gezeigt, wird die Mehrdeutigkeit durch umwandeln x in den entsprechenden Basis Schnittstellentyp aufgelöst.As illustrated by the example, the ambiguity is resolved by casting x to the appropriate base interface type. Solche Umwandlungen haben keine Lauf Zeit Kosten – Sie bestehen lediglich aus der Anzeige der Instanz als weniger abgeleiteter Typ zur Kompilierzeit.Such casts have no run-time costs—they merely consist of viewing the instance as a less derived type at compile-time.

Im BeispielIn the example

interface IInteger
{
    void Add(int i);
}

interface IDouble
{
    void Add(double d);
}

interface INumber: IInteger, IDouble {}

class C
{
    void Test(INumber n) {
        n.Add(1);                // Invokes IInteger.Add
        n.Add(1.0);              // Only IDouble.Add is applicable
        ((IInteger)n).Add(1);    // Only IInteger.Add is a candidate
        ((IDouble)n).Add(1);     // Only IDouble.Add is a candidate
    }
}

der Aufruf n.Add(1) IInteger.Add wird durch Anwenden der Regeln zur Überladungs Auflösung der Überladungs Auflösungausgewählt.the invocation n.Add(1) selects IInteger.Add by applying the overload resolution rules of Overload resolution. Entsprechend wählt der Aufruf n.Add(1.0) aus IDouble.Add .Similarly the invocation n.Add(1.0) selects IDouble.Add. Wenn explizite Umwandlungen eingefügt werden, gibt es nur eine Kandidaten Methode und somit keine Mehrdeutigkeit.When explicit casts are inserted, there is only one candidate method, and thus no ambiguity.

Im BeispielIn the example

interface IBase
{
    void F(int i);
}

interface ILeft: IBase
{
    new void F(int i);
}

interface IRight: IBase
{
    void G();
}

interface IDerived: ILeft, IRight {}

class A
{
    void Test(IDerived d) {
        d.F(1);                 // Invokes ILeft.F
        ((IBase)d).F(1);        // Invokes IBase.F
        ((ILeft)d).F(1);        // Invokes ILeft.F
        ((IRight)d).F(1);       // Invokes IBase.F
    }
}

der IBase.F Member wird vom Member ausgeblendet ILeft.F .the IBase.F member is hidden by the ILeft.F member. Der Aufruf d.F(1) wählt daher ILeft.F aus, obwohl IBase.F anscheinend nicht im Zugriffs Pfad verborgen ist, der durchführt IRight .The invocation d.F(1) thus selects ILeft.F, even though IBase.F appears to not be hidden in the access path that leads through IRight.

Die intuitive Regel für das Ausblenden von Schnittstellen mit mehreren Vererbungen ist einfach: Wenn ein Member in einem beliebigen Zugriffs Pfad ausgeblendet ist, wird er in allen Zugriffs Pfaden ausgeblendet.The intuitive rule for hiding in multiple-inheritance interfaces is simply this: If a member is hidden in any access path, it is hidden in all access paths. Da der Zugriffs Pfad von IDerived zu ILeft IBase IBase.F ausgeblendet wird, wird der-Member auch im Zugriffs Pfad von IDerived bis IRight zu ausgeblendet IBase .Because the access path from IDerived to ILeft to IBase hides IBase.F, the member is also hidden in the access path from IDerived to IRight to IBase.

Fully qualified interface member names (Vollqualifizierte Schnittstellenmembernamen)Fully qualified interface member names

Auf einen Schnittstellenmember wird manchmal durch seinen voll qualifizierten Namen verwiesen.An interface member is sometimes referred to by its fully qualified name. Der voll qualifizierte Name eines Schnittstellenmembers besteht aus dem Namen der Schnittstelle, in der der Member deklariert ist, gefolgt von einem Punkt, gefolgt vom Namen des Members.The fully qualified name of an interface member consists of the name of the interface in which the member is declared, followed by a dot, followed by the name of the member. Der voll qualifizierte Name eines Members verweist auf die Schnittstelle, in der der Member deklariert wird.The fully qualified name of a member references the interface in which the member is declared. Beispielsweise mit den DeklarationenFor example, given the declarations

interface IControl
{
    void Paint();
}

interface ITextBox: IControl
{
    void SetText(string text);
}

der voll qualifizierte Name von Paint ist, IControl.Paint und der voll qualifizierte Name von SetText ist ITextBox.SetText .the fully qualified name of Paint is IControl.Paint and the fully qualified name of SetText is ITextBox.SetText.

Im obigen Beispiel kann nicht auf als verwiesen werden Paint ITextBox.Paint .In the example above, it is not possible to refer to Paint as ITextBox.Paint.

Wenn eine Schnittstelle Teil eines Namespace ist, enthält der voll qualifizierte Name eines Schnittstellenmembers den Namespace Namen.When an interface is part of a namespace, the fully qualified name of an interface member includes the namespace name. Beispiel:For example

namespace System
{
    public interface ICloneable
    {
        object Clone();
    }
}

Hier lautet der voll qualifizierte Name der Clone Methode System.ICloneable.Clone .Here, the fully qualified name of the Clone method is System.ICloneable.Clone.

SchnittstellenimplementierungenInterface implementations

Schnittstellen können von Klassen und Strukturen implementiert werden.Interfaces may be implemented by classes and structs. Um anzugeben, dass eine Klasse oder Struktur direkt eine Schnittstelle implementiert, ist der Schnittstellen Bezeichner in der Basisklassen Liste der Klasse oder Struktur enthalten.To indicate that a class or struct directly implements an interface, the interface identifier is included in the base class list of the class or struct. Beispiel:For example:

interface ICloneable
{
    object Clone();
}

interface IComparable
{
    int CompareTo(object other);
}

class ListEntry: ICloneable, IComparable
{
    public object Clone() {...}
    public int CompareTo(object other) {...}
}

Eine Klasse oder Struktur, die eine Schnittstelle direkt implementiert, implementiert auch direkt alle Basis Schnittstellen der Schnittstelle.A class or struct that directly implements an interface also directly implements all of the interface's base interfaces implicitly. Dies gilt auch, wenn die Klasse oder Struktur nicht explizit alle Basis Schnittstellen in der Basisklassen Liste aufführt.This is true even if the class or struct doesn't explicitly list all base interfaces in the base class list. Beispiel:For example:

interface IControl
{
    void Paint();
}

interface ITextBox: IControl
{
    void SetText(string text);
}

class TextBox: ITextBox
{
    public void Paint() {...}
    public void SetText(string text) {...}
}

Hier implementiert Class TextBox sowohl IControl als auch ITextBox .Here, class TextBox implements both IControl and ITextBox.

Wenn eine Klasse C direkt eine Schnittstelle implementiert, implementieren alle Klassen, die von C abgeleitet sind, auch die-Schnittstelle implizit.When a class C directly implements an interface, all classes derived from C also implement the interface implicitly. Die in einer Klassen Deklaration angegebenen Basis Schnittstellen können als Schnittstellentypen (konstruierte Typen) erstellt werden.The base interfaces specified in a class declaration can be constructed interface types (Constructed types). Eine Basisschnittstelle kann nicht eigenständig ein Typparameter sein. Sie kann jedoch die Typparameter enthalten, die sich im Gültigkeitsbereich befinden.A base interface cannot be a type parameter on its own, though it can involve the type parameters that are in scope. Der folgende Code veranschaulicht, wie eine Klasse konstruierte Typen implementieren und erweitern kann:The following code illustrates how a class can implement and extend constructed types:

class C<U,V> {}

interface I1<V> {}

class D: C<string,int>, I1<string> {}

class E<T>: C<int,T>, I1<T> {}

Die Basis Schnittstellen einer generischen Klassen Deklaration müssen der in der Eindeutigkeit implementierter SchnittStelle beschriebenen Eindeutigkeits Regel entsprechen.The base interfaces of a generic class declaration must satisfy the uniqueness rule described in Uniqueness of implemented interfaces.

Explizite Schnittstellenmember-ImplementierungenExplicit interface member implementations

Zum Implementieren von Schnittstellen kann eine Klasse oder Struktur explizite Implementierungen von Schnittstellenmembern deklarieren.For purposes of implementing interfaces, a class or struct may declare explicit interface member implementations. Eine explizite Implementierung des Schnittstellenmembers ist eine Methode, eine Eigenschaft, ein Ereignis oder eine Indexerdeklaration, die auf einen voll qualifizierten schnittstellenelementnamen verweist.An explicit interface member implementation is a method, property, event, or indexer declaration that references a fully qualified interface member name. Beispiel:For example

interface IList<T>
{
    T[] GetElements();
}

interface IDictionary<K,V>
{
    V this[K key];
    void Add(K key, V value);
}

class List<T>: IList<T>, IDictionary<int,T>
{
    T[] IList<T>.GetElements() {...}
    T IDictionary<int,T>.this[int index] {...}
    void IDictionary<int,T>.Add(int index, T value) {...}
}

Hier IDictionary<int,T>.this und IDictionary<int,T>.Add sind explizite Schnittstellenmember-Implementierungen.Here IDictionary<int,T>.this and IDictionary<int,T>.Add are explicit interface member implementations.

In einigen Fällen ist der Name eines Schnittstellenmembers für die implementierende Klasse möglicherweise nicht geeignet. in diesem Fall kann der Schnittstellenmember mithilfe der expliziten Implementierung des Schnittstellenmembers implementiert werden.In some cases, the name of an interface member may not be appropriate for the implementing class, in which case the interface member may be implemented using explicit interface member implementation. Eine Klasse, die eine Datei Abstraktion implementiert, würde z. b. wahrscheinlich eine Element Funktion implementieren, die Close die Datei Ressource freigibt, und die- Dispose Methode der- IDisposable Schnittstelle mithilfe der expliziten Implementierung von Schnittstellen Membern implementieren:A class implementing a file abstraction, for example, would likely implement a Close member function that has the effect of releasing the file resource, and implement the Dispose method of the IDisposable interface using explicit interface member implementation:

interface IDisposable
{
    void Dispose();
}

class MyFile: IDisposable
{
    void IDisposable.Dispose() {
        Close();
    }

    public void Close() {
        // Do what's necessary to close the file
        System.GC.SuppressFinalize(this);
    }
}

Es ist nicht möglich, auf eine explizite Schnittstellenmember-Implementierung über den voll qualifizierten Namen in einem Methodenaufruf, dem Eigenschafts Zugriff oder dem Indexerzugriff zuzugreifen.It is not possible to access an explicit interface member implementation through its fully qualified name in a method invocation, property access, or indexer access. Auf eine explizite Schnittstellenmember-Implementierung kann nur über eine Schnittstellen Instanz zugegriffen werden, und in diesem Fall wird einfach anhand ihres Element namens darauf verwiesen.An explicit interface member implementation can only be accessed through an interface instance, and is in that case referenced simply by its member name.

Es handelt sich um einen Kompilierzeitfehler für eine explizite Schnittstellenmember-Implementierung, um Zugriffsmodifizierer einzuschließen, und es handelt sich um einen Kompilierungsfehler, der die Modifizierer abstract , virtual , override oder einschließt static .It is a compile-time error for an explicit interface member implementation to include access modifiers, and it is a compile-time error to include the modifiers abstract, virtual, override, or static.

Explizite Schnittstellenmember-Implementierungen haben unterschiedliche Barrierefreiheits Merkmale als andere Member.Explicit interface member implementations have different accessibility characteristics than other members. Da explizite Schnittstellenmember-Implementierungen nie über Ihren voll qualifizierten Namen in einem Methodenaufruf oder einem Eigenschaften Zugriff zugänglich sind, sind Sie in einem Sinn privat.Because explicit interface member implementations are never accessible through their fully qualified name in a method invocation or a property access, they are in a sense private. Da jedoch über eine Schnittstellen Instanz auf Sie zugegriffen werden kann, sind Sie auch öffentlich.However, since they can be accessed through an interface instance, they are in a sense also public.

Explizite Schnittstellenmember-Implementierungen dienen zwei Haupt Zwecken:Explicit interface member implementations serve two primary purposes:

  • Da die Implementierungen expliziter Schnittstellen Member nicht über Klassen-oder Struktur Instanzen zugänglich sind, können Schnittstellen Implementierungen von der öffentlichen Schnittstelle einer Klasse oder Struktur ausgeschlossen werden.Because explicit interface member implementations are not accessible through class or struct instances, they allow interface implementations to be excluded from the public interface of a class or struct. Dies ist besonders nützlich, wenn eine Klasse oder Struktur eine interne Schnittstelle implementiert, die für einen Consumer dieser Klasse oder Struktur nicht von Interesse ist.This is particularly useful when a class or struct implements an internal interface that is of no interest to a consumer of that class or struct.
  • Explizite Schnittstellenmember-Implementierungen ermöglichen die Eindeutigkeit von Schnittstellenmembern mit derselben Signatur.Explicit interface member implementations allow disambiguation of interface members with the same signature. Ohne explizite Implementierungen von Schnittstellenmembern wäre es für eine Klasse oder Struktur unmöglich, unterschiedliche Implementierungen von Schnittstellenmembern mit derselben Signatur und demselben Rückgabetyp zu haben. es ist nicht möglich, dass eine Klasse oder Struktur eine Implementierung für alle Schnittstellenmember mit derselben Signatur, aber mit unterschiedlichen Rückgabe Typen hat.Without explicit interface member implementations it would be impossible for a class or struct to have different implementations of interface members with the same signature and return type, as would it be impossible for a class or struct to have any implementation at all of interface members with the same signature but with different return types.

Damit eine explizite Schnittstellenmember-Implementierung gültig ist, muss die Klasse oder Struktur eine Schnittstelle in der Basisklassen Liste benennen, die ein Element enthält, dessen voll qualifizierter Name, Typ und Parametertypen exakt mit denen der expliziten Schnittstellenmember-Implementierung übereinstimmen.For an explicit interface member implementation to be valid, the class or struct must name an interface in its base class list that contains a member whose fully qualified name, type, and parameter types exactly match those of the explicit interface member implementation. Daher wird in der folgenden KlasseThus, in the following class

class Shape: ICloneable
{
    object ICloneable.Clone() {...}
    int IComparable.CompareTo(object other) {...}    // invalid
}

die Deklaration von IComparable.CompareTo führt zu einem Kompilierzeitfehler, da IComparable nicht in der Basisklassen Liste von aufgeführt ist Shape und keine Basisschnittstelle von ist ICloneable .the declaration of IComparable.CompareTo results in a compile-time error because IComparable is not listed in the base class list of Shape and is not a base interface of ICloneable. Ebenso in den DeklarationenLikewise, in the declarations

class Shape: ICloneable
{
    object ICloneable.Clone() {...}
}

class Ellipse: Shape
{
    object ICloneable.Clone() {...}    // invalid
}

die Deklaration von ICloneable.Clone in Ellipse führt zu einem Kompilierzeitfehler, da ICloneable nicht explizit in der Basisklassen Liste von aufgeführt wird Ellipse .the declaration of ICloneable.Clone in Ellipse results in a compile-time error because ICloneable is not explicitly listed in the base class list of Ellipse.

Der voll qualifizierte Name eines Schnittstellenmembers muss auf die Schnittstelle verweisen, in der der Member deklariert wurde.The fully qualified name of an interface member must reference the interface in which the member was declared. Folglich in den DeklarationenThus, in the declarations

interface IControl
{
    void Paint();
}

interface ITextBox: IControl
{
    void SetText(string text);
}

class TextBox: ITextBox
{
    void IControl.Paint() {...}
    void ITextBox.SetText(string text) {...}
}

die explizite Implementierung des Schnittstellenmembers von Paint muss als geschrieben werden IControl.Paint .the explicit interface member implementation of Paint must be written as IControl.Paint.

Eindeutigkeit der implementierten SchnittstellenUniqueness of implemented interfaces

Die von einer generischen Typdeklaration implementierten Schnittstellen müssen für alle möglichen konstruierten Typen eindeutig bleiben.The interfaces implemented by a generic type declaration must remain unique for all possible constructed types. Ohne diese Regel wäre es nicht möglich, die richtige Methode zu ermitteln, die für bestimmte konstruierte Typen aufgerufen werden soll.Without this rule, it would be impossible to determine the correct method to call for certain constructed types. Nehmen Sie beispielsweise an, dass eine generische Klassen Deklaration wie folgt geschrieben werden darf:For example, suppose a generic class declaration were permitted to be written as follows:

interface I<T>
{
    void F();
}

class X<U,V>: I<U>, I<V>                    // Error: I<U> and I<V> conflict
{
    void I<U>.F() {...}
    void I<V>.F() {...}
}

War dies zulässig, konnte nicht ermittelt werden, welcher Code im folgenden Fall ausgeführt werden soll:Were this permitted, it would be impossible to determine which code to execute in the following case:

I<int> x = new X<int,int>();
x.F();

Um zu ermitteln, ob die Schnittstellen Liste einer generischen Typdeklaration gültig ist, werden die folgenden Schritte ausgeführt:To determine if the interface list of a generic type declaration is valid, the following steps are performed:

  • Dies ist L die Liste der Schnittstellen, die direkt in einer generischen Klassen-, Struktur-oder Schnittstellen Deklaration angegeben werden C .Let L be the list of interfaces directly specified in a generic class, struct, or interface declaration C.
  • Fügen Sie L allen Basis Schnittstellen der Schnittstellen hinzu, die bereits in vorhanden sind L .Add to L any base interfaces of the interfaces already in L.
  • Entfernen Sie alle Duplikate aus L .Remove any duplicates from L.
  • Wenn ein möglicher konstruierter Typ, der von erstellt C wird, nach dem Ersetzen von Typargumenten ersetzt L werden muss, werden zwei Schnittstellen in L identisch sein, und die Deklaration von C ist ungültig.If any possible constructed type created from C would, after type arguments are substituted into L, cause two interfaces in L to be identical, then the declaration of C is invalid. Einschränkungs Deklarationen werden nicht berücksichtigt, wenn alle möglichen konstruierten Typen ermittelt werden.Constraint declarations are not considered when determining all possible constructed types.

In der obigen Klassen Deklaration X besteht die Schnittstellen Liste L aus I<U> und I<V> .In the class declaration X above, the interface list L consists of I<U> and I<V>. Die Deklaration ist ungültig, da ein konstruierter Typ mit U und V dem gleichen Typ dazu führen würde, dass diese beiden Schnittstellen identische Typen darstellen.The declaration is invalid because any constructed type with U and V being the same type would cause these two interfaces to be identical types.

Es ist möglich, dass die Schnittstellen, die auf unterschiedlichen Vererbungs Ebenen angegeben werden,It is possible for interfaces specified at different inheritance levels to unify:

interface I<T>
{
    void F();
}

class Base<U>: I<U>
{
    void I<U>.F() {...}
}

class Derived<U,V>: Base<U>, I<V>    // Ok
{
    void I<V>.F() {...}
}

Dieser Code ist gültig, obwohl Derived<U,V> sowohl als auch implementiert I<U> I<V> .This code is valid even though Derived<U,V> implements both I<U> and I<V>. Der CodeThe code

I<int> x = new Derived<int,int>();
x.F();

Ruft die-Methode in auf Derived , da Derived<int,int> tatsächlich neu implementiert I<int> (Schnittstellen erneute Implementierung).invokes the method in Derived, since Derived<int,int> effectively re-implements I<int> (Interface re-implementation).

Implementierung generischer MethodenImplementation of generic methods

Wenn eine generische Methode implizit eine Schnittstellen Methode implementiert, müssen die Einschränkungen, die für jeden Methodentypparameter angegeben werden, in beiden Deklarationen äquivalent sein (nachdem alle Schnittstellen Typparameter durch die entsprechenden Typargumente ersetzt wurden), wobei Methodentypparameter durch Ordinalpositionen von links nach rechts identifiziert werden.When a generic method implicitly implements an interface method, the constraints given for each method type parameter must be equivalent in both declarations (after any interface type parameters are replaced with the appropriate type arguments), where method type parameters are identified by ordinal positions, left to right.

Wenn eine generische Methode explizit eine Schnittstellen Methode implementiert, sind jedoch keine Einschränkungen für die implementierende Methode zulässig.When a generic method explicitly implements an interface method, however, no constraints are allowed on the implementing method. Stattdessen werden die Einschränkungen von der Schnittstellen Methode geerbt.Instead, the constraints are inherited from the interface method

interface I<A,B,C>
{
    void F<T>(T t) where T: A;
    void G<T>(T t) where T: B;
    void H<T>(T t) where T: C;
}

class C: I<object,C,string>
{
    public void F<T>(T t) {...}                    // Ok
    public void G<T>(T t) where T: C {...}         // Ok
    public void H<T>(T t) where T: string {...}    // Error
}

Die-Methode C.F<T> implementiert implizit I<object,C,string>.F<T> .The method C.F<T> implicitly implements I<object,C,string>.F<T>. In diesem Fall C.F<T> ist nicht erforderlich (und nicht zulässig), um die Einschränkung anzugeben, T:object da object eine implizite Einschränkung für alle Typparameter ist.In this case, C.F<T> is not required (nor permitted) to specify the constraint T:object since object is an implicit constraint on all type parameters. Die-Methode C.G<T> implementiert implizit I<object,C,string>.G<T> , da die Einschränkungen mit denen in der-Schnittstelle übereinstimmen, nachdem die Schnittstellen Typparameter durch die entsprechenden Typargumente ersetzt wurden.The method C.G<T> implicitly implements I<object,C,string>.G<T> because the constraints match those in the interface, after the interface type parameters are replaced with the corresponding type arguments. Die Einschränkung für die-Methode C.H<T> ist ein Fehler, da versiegelte Typen ( string in diesem Fall) nicht als Einschränkungen verwendet werden können.The constraint for method C.H<T> is an error because sealed types (string in this case) cannot be used as constraints. Das Weglassen der Einschränkung wäre auch ein Fehler, da Einschränkungen von impliziten Schnittstellen Methoden Implementierungen erforderlich sind, um eine Entsprechung zu finden.Omitting the constraint would also be an error since constraints of implicit interface method implementations are required to match. Daher ist es unmöglich, implizit zu implementieren I<object,C,string>.H<T> .Thus, it is impossible to implicitly implement I<object,C,string>.H<T>. Diese Schnittstellen Methode kann nur mit einer expliziten Schnittstellenmember-Implementierung implementiert werden:This interface method can only be implemented using an explicit interface member implementation:

class C: I<object,C,string>
{
    ...

    public void H<U>(U u) where U: class {...}

    void I<object,C,string>.H<T>(T t) {
        string s = t;    // Ok
        H<T>(t);
    }
}

In diesem Beispiel ruft die explizite Implementierung des Schnittstellenmembers eine öffentliche Methode auf, die streng schwächere Einschränkungen hat.In this example, the explicit interface member implementation invokes a public method having strictly weaker constraints. Beachten Sie, dass die Zuweisung von t zu s gültig ist T , da eine Einschränkung von erbt T:string , auch wenn diese Einschränkung im Quellcode nicht ausdrucksfähig ist.Note that the assignment from t to s is valid since T inherits a constraint of T:string, even though this constraint is not expressible in source code.

Schnittstellen ZuordnungInterface mapping

Eine Klasse oder Struktur muss Implementierungen aller Member der Schnittstellen bereitstellen, die in der Basisklassen Liste der Klasse oder Struktur aufgeführt sind.A class or struct must provide implementations of all members of the interfaces that are listed in the base class list of the class or struct. Der Prozess der Suche nach Implementierungen von Schnittstellenmembern in einer implementierenden Klasse oder Struktur wird als Schnittstellen Zuordnung bezeichnet.The process of locating implementations of interface members in an implementing class or struct is known as interface mapping.

Bei der Schnittstellen Zuordnung für eine Klasse oder Struktur wird C eine Implementierung für jedes Element jeder Schnittstelle gesucht, die in der Basisklassen Liste von angegeben ist C .Interface mapping for a class or struct C locates an implementation for each member of each interface specified in the base class list of C. Die Implementierung eines bestimmten Schnittstellenmembers I.M , wobei I die Schnittstelle ist, in der der Member M deklariert wird, wird durch Untersuchen der einzelnen Klassen oder Strukturen S , beginnend mit C und wiederholen für jede aufeinander folgende Basisklasse von C , bis eine Entsprechung gefunden wird:The implementation of a particular interface member I.M, where I is the interface in which the member M is declared, is determined by examining each class or struct S, starting with C and repeating for each successive base class of C, until a match is located:

  • Wenn S eine Deklaration einer expliziten Schnittstellenmember-Implementierung enthält, die mit und übereinstimmt I M , dann ist dieser Member die Implementierung von I.M .If S contains a declaration of an explicit interface member implementation that matches I and M, then this member is the implementation of I.M.
  • Wenn andernfalls S eine Deklaration eines nicht statischen öffentlichen Members enthält, der entspricht M , ist dieser Member die Implementierung von I.M .Otherwise, if S contains a declaration of a non-static public member that matches M, then this member is the implementation of I.M. Wenn mehr als ein Member übereinstimmt, wird nicht angegeben, welcher Member die Implementierung von ist I.M .If more than one member matches, it is unspecified which member is the implementation of I.M. Diese Situation kann nur auftreten S , wenn ein konstruierter Typ ist, bei dem die beiden Member, die im generischen Typ deklariert sind, über unterschiedliche Signaturen verfügen, aber die Typargumente die Signaturen identisch machen.This situation can only occur if S is a constructed type where the two members as declared in the generic type have different signatures, but the type arguments make their signatures identical.

Ein Kompilierzeitfehler tritt auf, wenn-Implementierungen nicht für alle Elemente aller Schnittstellen gefunden werden können, die in der Basisklassen Liste von angegeben sind C .A compile-time error occurs if implementations cannot be located for all members of all interfaces specified in the base class list of C. Beachten Sie, dass die Member einer Schnittstelle jene Member enthalten, die von Basis Schnittstellen geerbt werden.Note that the members of an interface include those members that are inherited from base interfaces.

Zum Zwecke der Schnittstellen Zuordnung entspricht ein Klassenmember einem A Schnittstellenmember in folgenden Fällen B :For purposes of interface mapping, a class member A matches an interface member B when:

  • A und B sind-Methoden, und der Name, der Typ und die formalen Parameterlisten von A und B sind identisch.A and B are methods, and the name, type, and formal parameter lists of A and B are identical.
  • A und B sind Eigenschaften, der Name und der Typ von A und B sind identisch, und A verfügt über dieselben Accessoren wie B ( A ist berechtigt, zusätzliche Accessoren zu haben, wenn es sich nicht um eine explizite Schnittstellenmember-Implementierung handelt).A and B are properties, the name and type of A and B are identical, and A has the same accessors as B (A is permitted to have additional accessors if it is not an explicit interface member implementation).
  • A und B sind-Ereignisse, und der Name und der Typ von A und B sind identisch.A and B are events, and the name and type of A and B are identical.
  • A und B sind Indexer, der Typ und die formalen Parameterlisten von A und B sind identisch, und weisen A dieselben Accessoren wie B auf ( A ist für zusätzliche Accessoren zulässig, wenn es sich nicht um eine explizite Schnittstellenmember-Implementierung handelt).A and B are indexers, the type and formal parameter lists of A and B are identical, and A has the same accessors as B (A is permitted to have additional accessors if it is not an explicit interface member implementation).

Wichtige Implikationen des Schnittstellen Mapping-Algorithmus:Notable implications of the interface mapping algorithm are:

  • Explizite Schnittstellenmember-Implementierungen haben Vorrang vor anderen Membern in derselben Klasse oder Struktur, wenn Sie die Klasse oder den Strukturmember ermitteln, der einen Schnittstellenmember implementiert.Explicit interface member implementations take precedence over other members in the same class or struct when determining the class or struct member that implements an interface member.
  • Keines der nicht öffentlichen und statischen Member ist an der Schnittstellen Zuordnung beteiligt.Neither non-public nor static members participate in interface mapping.

Im BeispielIn the example

interface ICloneable
{
    object Clone();
}

class C: ICloneable
{
    object ICloneable.Clone() {...}
    public object Clone() {...}
}

der ICloneable.Clone Member von C wird zur Implementierung von Clone in, ICloneable da explizite Schnittstellenmember-Implementierungen Vorrang vor anderen Membern haben.the ICloneable.Clone member of C becomes the implementation of Clone in ICloneable because explicit interface member implementations take precedence over other members.

Wenn eine Klasse oder Struktur zwei oder mehr Schnittstellen implementiert, die einen Member mit demselben Namen, Typ und denselben Parametertypen enthalten, ist es möglich, jedes dieser Schnittstellenmember einer einzelnen Klasse oder einem Strukturelement zuzuordnen.If a class or struct implements two or more interfaces containing a member with the same name, type, and parameter types, it is possible to map each of those interface members onto a single class or struct member. Beispiel:For example

interface IControl
{
    void Paint();
}

interface IForm
{
    void Paint();
}

class Page: IControl, IForm
{
    public void Paint() {...}
}

Hier werden die Paint Methoden von IControl und IForm auf der- Paint Methode in zugeordnet Page .Here, the Paint methods of both IControl and IForm are mapped onto the Paint method in Page. Natürlich ist es auch möglich, dass Sie über separate explizite Schnittstellenmember-Implementierungen für die beiden Methoden verfügen.It is of course also possible to have separate explicit interface member implementations for the two methods.

Wenn eine Klasse oder Struktur eine Schnittstelle implementiert, die ausgeblendete Member enthält, müssen einige Member notwendigerweise durch explizite Implementierungen von Schnittstellenmembern implementiert werden.If a class or struct implements an interface that contains hidden members, then some members must necessarily be implemented through explicit interface member implementations. Beispiel:For example

interface IBase
{
    int P { get; }
}

interface IDerived: IBase
{
    new int P();
}

Eine Implementierung dieser Schnittstelle erfordert mindestens eine explizite Implementierung des Schnittstellenmembers und würde eine der folgenden Formen annehmen:An implementation of this interface would require at least one explicit interface member implementation, and would take one of the following forms

class C: IDerived
{
    int IBase.P { get {...} }
    int IDerived.P() {...}
}

class C: IDerived
{
    public int P { get {...} }
    int IDerived.P() {...}
}

class C: IDerived
{
    int IBase.P { get {...} }
    public int P() {...}
}

Wenn eine Klasse mehrere Schnittstellen implementiert, die über dieselbe Basisschnittstelle verfügen, kann nur eine Implementierung der Basisschnittstelle vorhanden sein.When a class implements multiple interfaces that have the same base interface, there can be only one implementation of the base interface. Im BeispielIn the example

interface IControl
{
    void Paint();
}

interface ITextBox: IControl
{
    void SetText(string text);
}

interface IListBox: IControl
{
    void SetItems(string[] items);
}

class ComboBox: IControl, ITextBox, IListBox
{
    void IControl.Paint() {...}
    void ITextBox.SetText(string text) {...}
    void IListBox.SetItems(string[] items) {...}
}

Es ist nicht möglich, separate Implementierungen für den IControl benannten in der Basisklassen Liste, den IControl von geerbten ITextBox und den IControl von geerbten IListBox zu haben.it is not possible to have separate implementations for the IControl named in the base class list, the IControl inherited by ITextBox, and the IControl inherited by IListBox. Tatsächlich gibt es keine andere Identität für diese Schnittstellen.Indeed, there is no notion of a separate identity for these interfaces. Stattdessen verwenden die Implementierungen von ITextBox und IListBox die gleiche Implementierung von und IControl werden lediglich für die Implementierung von ComboBox drei Schnittstellen, IControl , ITextBox und berücksichtigt IListBox .Rather, the implementations of ITextBox and IListBox share the same implementation of IControl, and ComboBox is simply considered to implement three interfaces, IControl, ITextBox, and IListBox.

Die Member einer Basisklasse werden an der Schnittstellen Zuordnung beteiligt.The members of a base class participate in interface mapping. Im BeispielIn the example

interface Interface1
{
    void F();
}

class Class1
{
    public void F() {}
    public void G() {}
}

class Class2: Class1, Interface1
{
    new public void G() {}
}

die F -Methode in Class1 wird in der Class2 -Implementierung von verwendet Interface1 .the method F in Class1 is used in Class2's implementation of Interface1.

Vererbung der Schnittstellen ImplementierungInterface implementation inheritance

Eine Klasse erbt alle Schnittstellen Implementierungen, die von ihren Basisklassen bereitgestellt werden.A class inherits all interface implementations provided by its base classes.

Ohne eine explizite Neuimplementierung einer Schnittstelle kann eine abgeleitete Klasse die Schnittstellen Zuordnungen, die Sie von ihren Basisklassen erbt, nicht ändern.Without explicitly re-implementing an interface, a derived class cannot in any way alter the interface mappings it inherits from its base classes. Beispielsweise in den DeklarationenFor example, in the declarations

interface IControl
{
    void Paint();
}

class Control: IControl
{
    public void Paint() {...}
}

class TextBox: Control
{
    new public void Paint() {...}
}

die Paint -Methode in TextBox Paint blendet die-Methode in aus Control , ändert aber nicht die Zuordnung von Control.Paint IControl.Paint zu, und Aufrufe von Paint über Klassen Instanzen und Schnittstellen Instanzen haben die folgenden Auswirkungen:the Paint method in TextBox hides the Paint method in Control, but it does not alter the mapping of Control.Paint onto IControl.Paint, and calls to Paint through class instances and interface instances will have the following effects

Control c = new Control();
TextBox t = new TextBox();
IControl ic = c;
IControl it = t;
c.Paint();            // invokes Control.Paint();
t.Paint();            // invokes TextBox.Paint();
ic.Paint();           // invokes Control.Paint();
it.Paint();           // invokes Control.Paint();

Wenn eine Schnittstellen Methode jedoch einer virtuellen Methode in einer Klasse zugeordnet ist, kann es vorkommen, dass abgeleitete Klassen die virtuelle Methode überschreiben und die Implementierung der Schnittstelle ändern.However, when an interface method is mapped onto a virtual method in a class, it is possible for derived classes to override the virtual method and alter the implementation of the interface. Beispielsweise das Umschreiben der obigen Deklarationen inFor example, rewriting the declarations above to

interface IControl
{
    void Paint();
}

class Control: IControl
{
    public virtual void Paint() {...}
}

class TextBox: Control
{
    public override void Paint() {...}
}

die folgenden Effekte werden nun beobachtet.the following effects will now be observed

Control c = new Control();
TextBox t = new TextBox();
IControl ic = c;
IControl it = t;
c.Paint();            // invokes Control.Paint();
t.Paint();            // invokes TextBox.Paint();
ic.Paint();           // invokes Control.Paint();
it.Paint();           // invokes TextBox.Paint();

Da explizite Implementierungen von Schnittstellen Membern nicht als virtuell deklariert werden können, ist es nicht möglich, eine explizite Schnittstellenmember-Implementierung zu überschreiben.Since explicit interface member implementations cannot be declared virtual, it is not possible to override an explicit interface member implementation. Allerdings ist es für eine explizite Schnittstellenmember-Implementierung durchaus gültig, eine andere Methode aufzurufen, und diese andere Methode kann als virtuell deklariert werden, damit abgeleitete Klassen Sie überschreiben können.However, it is perfectly valid for an explicit interface member implementation to call another method, and that other method can be declared virtual to allow derived classes to override it. Beispiel:For example

interface IControl
{
    void Paint();
}

class Control: IControl
{
    void IControl.Paint() { PaintControl(); }
    protected virtual void PaintControl() {...}
}

class TextBox: Control
{
    protected override void PaintControl() {...}
}

Hier können von abgeleitete Klassen Control die-Implementierung von spezialisieren, IControl.Paint indem die-Methode überschrieben wird PaintControl .Here, classes derived from Control can specialize the implementation of IControl.Paint by overriding the PaintControl method.

Neuimplementierung der SchnittstelleInterface re-implementation

Eine Klasse, die eine Schnittstellen Implementierung erbt, kann die-Schnittstelle erneut implementieren , indem Sie in die Basisklassen Liste eingeschlossen wird.A class that inherits an interface implementation is permitted to re-implement the interface by including it in the base class list.

Eine erneute Implementierung einer Schnittstelle folgt genau denselben Schnittstellen Mapping-Regeln wie eine anfängliche Implementierung einer Schnittstelle.A re-implementation of an interface follows exactly the same interface mapping rules as an initial implementation of an interface. Folglich hat die geerbte Schnittstellen Zuordnung keinerlei Auswirkungen auf die Schnittstellen Zuordnung, die für die erneute Implementierung der Schnittstelle eingerichtet wurde.Thus, the inherited interface mapping has no effect whatsoever on the interface mapping established for the re-implementation of the interface. Beispielsweise in den DeklarationenFor example, in the declarations

interface IControl
{
    void Paint();
}

class Control: IControl
{
    void IControl.Paint() {...}
}

class MyControl: Control, IControl
{
    public void Paint() {}
}

die Tatsache, dass sich Zuordnungen Control IControl.Paint auf Control.IControl.Paint nicht auf die erneute Implementierung in auswirkt MyControl , die zugeordnet wird IControl.Paint MyControl.Paint .the fact that Control maps IControl.Paint onto Control.IControl.Paint doesn't affect the re-implementation in MyControl, which maps IControl.Paint onto MyControl.Paint.

Geerbte öffentliche Element Deklarationen und geerbte explizite Schnittstellenmember-Deklarationen nehmen am Schnittstellen Zuordnungsprozess für neu implementierte Schnittstellen TeilInherited public member declarations and inherited explicit interface member declarations participate in the interface mapping process for re-implemented interfaces. Beispiel:For example

interface IMethods
{
    void F();
    void G();
    void H();
    void I();
}

class Base: IMethods
{
    void IMethods.F() {}
    void IMethods.G() {}
    public void H() {}
    public void I() {}
}

class Derived: Base, IMethods
{
    public void F() {}
    void IMethods.H() {}
}

Hier ordnet die-Implementierung von IMethods in Derived die Schnittstellen Methoden auf Derived.F , Base.IMethods.G , Derived.IMethods.H und zu Base.I .Here, the implementation of IMethods in Derived maps the interface methods onto Derived.F, Base.IMethods.G, Derived.IMethods.H, and Base.I.

Wenn eine Klasse eine Schnittstelle implementiert, implementiert Sie implizit auch alle Basis Schnittstellen dieser Schnittstelle.When a class implements an interface, it implicitly also implements all of that interface's base interfaces. Ebenso ist eine erneute Implementierung einer Schnittstelle implizit eine erneute Implementierung aller Basis Schnittstellen der Schnittstelle.Likewise, a re-implementation of an interface is also implicitly a re-implementation of all of the interface's base interfaces. Beispiel:For example

interface IBase
{
    void F();
}

interface IDerived: IBase
{
    void G();
}

class C: IDerived
{
    void IBase.F() {...}
    void IDerived.G() {...}
}

class D: C, IDerived
{
    public void F() {...}
    public void G() {...}
}

Hier wird die erneute Implementierung von IDerived ebenfalls neu implementiert, wobei eine Zuordnung zu durchführt IBase IBase.F D.F .Here, the re-implementation of IDerived also re-implements IBase, mapping IBase.F onto D.F.

Abstrakte Klassen und SchnittstellenAbstract classes and interfaces

Wie eine nicht abstrakte Klasse muss eine abstrakte Klasse Implementierungen aller Member der Schnittstellen bereitstellen, die in der Basisklassen Liste der Klasse aufgelistet sind.Like a non-abstract class, an abstract class must provide implementations of all members of the interfaces that are listed in the base class list of the class. Eine abstrakte Klasse darf jedoch Schnittstellen Methoden zu abstrakten Methoden zuordnen.However, an abstract class is permitted to map interface methods onto abstract methods. Beispiel:For example

interface IMethods
{
    void F();
    void G();
}

abstract class C: IMethods
{
    public abstract void F();
    public abstract void G();
}

Hier ist die Implementierung von IMethods Maps F und G abstrakten Methoden, die in nicht abstrakten Klassen, die von abgeleitet werden, überschrieben werden müssen C .Here, the implementation of IMethods maps F and G onto abstract methods, which must be overridden in non-abstract classes that derive from C.

Beachten Sie, dass explizite Implementierungen von Schnittstellen Membern nicht abstrakt sein können, aber explizite Implementierungen von Schnittstellen Membern sind natürlich berechtigt, abstrakte Methoden aufzurufen.Note that explicit interface member implementations cannot be abstract, but explicit interface member implementations are of course permitted to call abstract methods. Beispiel:For example

interface IMethods
{
    void F();
    void G();
}

abstract class C: IMethods
{
    void IMethods.F() { FF(); }
    void IMethods.G() { GG(); }
    protected abstract void FF();
    protected abstract void GG();
}

Hier müssten nicht abstrakte Klassen, die von abgeleitet C werden, FF und GG die tatsächliche Implementierung von überschreiben IMethods .Here, non-abstract classes that derive from C would be required to override FF and GG, thus providing the actual implementation of IMethods.