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 parameterT
ist ein Arraytyp mit einem Ausgabe unsicheren Elementtyp.T
is an array type with an output-unsafe element typeT
ist eine Schnittstelle oder ein Delegattyp, derS<A1,...,Ak>
aus einem generischen Typ erstellt wird,S<X1,...,Xk>
wobei mindestens einer derAi
folgenden Punkte enthält:T
is an interface or delegate typeS<A1,...,Ak>
constructed from a generic typeS<X1,...,Xk>
where for at least oneAi
one of the following holds:Xi
ist kovariant oder invariante undAi
ist Ausgabe unsicher.Xi
is covariant or invariant andAi
is output-unsafe.Xi
ist kontra Variant oder invariante undAi
ist Eingabe sicher.Xi
is contravariant or invariant andAi
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 parameterT
ist ein Arraytyp mit einem Eingabe unsicheren Elementtyp.T
is an array type with an input-unsafe element typeT
ist eine Schnittstelle oder ein Delegattyp, derS<A1,...,Ak>
aus einem generischen Typ erstellt wird,S<X1,...,Xk>
wobei mindestens einer derAi
folgenden Punkte enthält:T
is an interface or delegate typeS<A1,...,Ak>
constructed from a generic typeS<X1,...,Xk>
where for at least oneAi
one of the following holds:Xi
ist kovariant oder invariante undAi
ist Eingabe unsicher.Xi
is covariant or invariant andAi
is input-unsafe.Xi
ist kontra Variant oder invariante undAi
ist Ausgabe unsicher.Xi
is contravariant or invariant andAi
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:
Xi
ist kovariant, und ein impliziter Verweis oder eine Identitäts Konvertierung ist von in vorhanden.Ai``Bi
Xi
is covariant and an implicit reference or identity conversion exists fromAi
toBi
Xi
ist kontra Variant, und ein impliziter Verweis oder eine Identitäts Konvertierung ist vonBi
zuAi
Xi
is contravariant and an implicit reference or identity conversion exists fromBi
toAi
Xi
ist invariante, und eine Identitäts Konvertierung ist vonAi
zuBi
Xi
is invariant and an identity conversion exists fromAi
toBi
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 byref
andout
. - 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 werdenC
.LetL
be the list of interfaces directly specified in a generic class, struct, or interface declarationC
. - Fügen Sie
L
allen Basis Schnittstellen der Schnittstellen hinzu, die bereits in vorhanden sindL
.Add toL
any base interfaces of the interfaces already inL
. - Entfernen Sie alle Duplikate aus
L
.Remove any duplicates fromL
. - Wenn ein möglicher konstruierter Typ, der von erstellt
C
wird, nach dem Ersetzen von Typargumenten ersetztL
werden muss, werden zwei Schnittstellen inL
identisch sein, und die Deklaration vonC
ist ungültig.If any possible constructed type created fromC
would, after type arguments are substituted intoL
, cause two interfaces inL
to be identical, then the declaration ofC
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 übereinstimmtI
M
, dann ist dieser Member die Implementierung vonI.M
.IfS
contains a declaration of an explicit interface member implementation that matchesI
andM
, then this member is the implementation ofI.M
. - Wenn andernfalls
S
eine Deklaration eines nicht statischen öffentlichen Members enthält, der entsprichtM
, ist dieser Member die Implementierung vonI.M
.Otherwise, ifS
contains a declaration of a non-static public member that matchesM
, then this member is the implementation ofI.M
. Wenn mehr als ein Member übereinstimmt, wird nicht angegeben, welcher Member die Implementierung von istI.M
.If more than one member matches, it is unspecified which member is the implementation ofI.M
. Diese Situation kann nur auftretenS
, 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 ifS
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
undB
sind-Methoden, und der Name, der Typ und die formalen Parameterlisten vonA
undB
sind identisch.A
andB
are methods, and the name, type, and formal parameter lists ofA
andB
are identical.A
undB
sind Eigenschaften, der Name und der Typ vonA
undB
sind identisch, undA
verfügt über dieselben Accessoren wieB
(A
ist berechtigt, zusätzliche Accessoren zu haben, wenn es sich nicht um eine explizite Schnittstellenmember-Implementierung handelt).A
andB
are properties, the name and type ofA
andB
are identical, andA
has the same accessors asB
(A
is permitted to have additional accessors if it is not an explicit interface member implementation).A
undB
sind-Ereignisse, und der Name und der Typ vonA
undB
sind identisch.A
andB
are events, and the name and type ofA
andB
are identical.A
undB
sind Indexer, der Typ und die formalen Parameterlisten vonA
undB
sind identisch, und weisenA
dieselben Accessoren wieB
auf (A
ist für zusätzliche Accessoren zulässig, wenn es sich nicht um eine explizite Schnittstellenmember-Implementierung handelt).A
andB
are indexers, the type and formal parameter lists ofA
andB
are identical, andA
has the same accessors asB
(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
.