InterfejsyInterfaces

Interfejs definiuje kontrakt.An interface defines a contract. Klasa lub struktura, która implementuje interfejs musi być zgodne z jego umową.A class or struct that implements an interface must adhere to its contract. Interfejs może dziedziczyć z wielu interfejsach podstawowych, a klasa lub struktura może zaimplementować wiele interfejsów.An interface may inherit from multiple base interfaces, and a class or struct may implement multiple interfaces.

Interfejsy mogą zawierać metody, właściwości, zdarzeń i indeksatorów.Interfaces can contain methods, properties, events, and indexers. Interfejs, sama nie zapewnia implementacje dla elementów członkowskich, które definiuje.The interface itself does not provide implementations for the members that it defines. Interfejs określa jedynie elementy członkowskie, które muszą być dostarczane przez klasy lub struktury, które implementują interfejs.The interface merely specifies the members that must be supplied by classes or structs that implement the interface.

Deklaracje interfejsuInterface declarations

Interface_declaration jest type_declaration (wpisz deklaracje) oświadcza, że nowy typ interfejsu.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 ';'?
    ;

Interface_declaration zawiera opcjonalny zestaw atrybuty (atrybuty), a następnie opcjonalny zestaw interface_modifiers (interfejsu Modyfikatory), a następnie opcjonalnie partial modyfikator, następuje słowa kluczowego interface i identyfikator , nazwy interfejsu, następuje opcjonalny variant_type_parameter_list specyfikacji (list parametrów typu Variant), a następnie opcjonalnie interface_base Specyfikacja (podstawowa interfejsów), a następnie opcjonalnie type_parameter_constraints_clausespecyfikacji s (ograniczenia parametru typu) , a następnie interface_body (interfejsu treści), opcjonalnie następuje średnik.An interface_declaration consists of an optional set of attributes (Attributes), followed by an optional set of interface_modifiers (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_clauses specification (Type parameter constraints), followed by an interface_body (Interface body), optionally followed by a semicolon.

Modyfikatory interfejsuInterface modifiers

Interface_declaration może opcjonalnie obejmować sekwencję Modyfikatory interfejsu:An interface_declaration may optionally include a sequence of interface modifiers:

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

Jest to błąd czasu kompilacji dla tego samego modyfikator pojawią się wiele razy w deklaracji interfejsu.It is a compile-time error for the same modifier to appear multiple times in an interface declaration.

new Modyfikator jest dozwolona tylko w interfejsach zdefiniowany w klasie.The new modifier is only permitted on interfaces defined within a class. Określa, że interfejs ukrywa dziedziczonej składowej o tej samej nazwie, zgodnie z opisem w nowy modyfikator.It specifies that the interface hides an inherited member by the same name, as described in The new modifier.

public, protected, internal, I private Modyfikatory kontrolować ułatwień dostępu interfejsu.The public, protected, internal, and private modifiers control the accessibility of the interface. W zależności od kontekstu, w którym występuje deklaracja interfejsu, tylko niektóre z tych modyfikatorów mogą być dozwolone (zadeklarowana dostępność).Depending on the context in which the interface declaration occurs, only some of these modifiers may be permitted (Declared accessibility).

Modyfikatora "Partial"Partial modifier

partial Modyfikator wskazuje, że to interface_declaration jest deklaracją typu częściowego.The partial modifier indicates that this interface_declaration is a partial type declaration. Łączenie wielu deklaracjach częściowej interfejsu o takiej samej nazwie w deklaracji otaczającego przestrzeń nazw lub typ do postaci jednego interfejsu deklaracji, zgodnie z regułami określone w typów częściowych.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.

Listy parametrów typu VariantVariant type parameter lists

Listy parametrów typu Variant może nastąpić tylko na typy interfejsów i delegatów.Variant type parameter lists can only occur on interface and delegate types. Różnica od zwykłych type_parameter_lists jest opcjonalny variance_annotation dla każdego parametru typu.The difference from ordinary type_parameter_lists 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'
    ;

Jeśli jest adnotacji wariancji out, parametr typu jest określany jako kowariantne.If the variance annotation is out, the type parameter is said to be covariant. Jeśli jest adnotacji wariancji in, parametr typu jest określany jako kontrawariantne.If the variance annotation is in, the type parameter is said to be contravariant. Jeśli nie ma żadnych adnotacji wariancji, parametr typu jest określany jako niezmiennej.If there is no variance annotation, the type parameter is said to be invariant.

W przykładzieIn the example

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

X jest kowariantny, Y jest kontrawariantny i Z jest niezmienny.X is covariant, Y is contravariant and Z is invariant.

Wariancja bezpieczeństwaVariance safety

Wystąpienie adnotacje dotyczące wariancji na liście parametrów typu typu ogranicza miejsca, w którym typów może mieć miejsce w deklaracji typu.The occurrence of variance annotations in the type parameter list of a type restricts the places where types can occur within the type declaration.

Typ T jest niebezpiecznych danych wyjściowych jeśli posiada jedną z następujących czynności:A type T is output-unsafe if one of the following holds:

  • T jest kontrawariantnego parametru typuT is a contravariant type parameter
  • T jest typem tablicy o typie elementu niebezpiecznych danych wyjściowychT is an array type with an output-unsafe element type
  • T Typ interfejsu lub delegata S<A1,...,Ak> skonstruowany z typu ogólnego S<X1,...,Xk> miejsca dla co najmniej jednej Ai zawiera jedną z następujących czynności: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 jest kowariantny lub niezmiennej i Ai jest niebezpieczne danych wyjściowych.Xi is covariant or invariant and Ai is output-unsafe.
    • Xi jest kontrawariantny lub niezmiennej i Ai jest bezpieczna pod względem danych wejściowych.Xi is contravariant or invariant and Ai is input-safe.

Typ T jest niebezpiecznych danych wejściowych jeśli posiada jedną z następujących czynności:A type T is input-unsafe if one of the following holds:

  • T jest kowariantny parametr typuT is a covariant type parameter
  • T jest typem tablicy o typie elementu niebezpiecznych danych wejściowychT is an array type with an input-unsafe element type
  • T Typ interfejsu lub delegata S<A1,...,Ak> skonstruowany z typu ogólnego S<X1,...,Xk> miejsca dla co najmniej jednej Ai zawiera jedną z następujących czynności: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 jest kowariantny lub niezmiennej i Ai jest niebezpieczne danych wejściowych.Xi is covariant or invariant and Ai is input-unsafe.
    • Xi jest kontrawariantny lub niezmiennej i Ai jest niebezpieczne danych wyjściowych.Xi is contravariant or invariant and Ai is output-unsafe.

Intuicyjne typem niebezpiecznych danych wyjściowych jest zabronione w pozycji danych wyjściowych, a typem niebezpiecznych danych wejściowych jest zabronione w pozycji danych wejściowych.Intuitively, an output-unsafe type is prohibited in an output position, and an input-unsafe type is prohibited in an input position.

Typ jest bezpieczne pod względem danych wyjściowych Jeśli nie jest dane wyjściowe — zagrożenie, i bezpieczne pod względem danych wejściowych Jeśli nie jest niebezpieczne danych wejściowych.A type is output-safe if it is not output-unsafe, and input-safe if it is not input-unsafe.

Konwersja wariancjiVariance conversion

Adnotacje dotyczące wariancji ma na celu zapewnienia bardziej łagodne (ale nadal bezpiecznego typu) konwersji na typy interfejsów i delegatów.The purpose of variance annotations is to provide for more lenient (but still type safe) conversions to interface and delegate types. W tym celu definicje niejawne (niejawne konwersje) i jawne konwersje (jawne konwersje) upewnij użytkowania pojęcie wariancji — przetwarzania, która jest zdefiniowana w następujący sposób: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:

Typ T<A1,...,An> jest odchylenie przekonwertować na typ T<B1,...,Bn> Jeśli T interfejsem lub typem obiektu delegowanego jest zadeklarowana z parametrami typu variant T<X1,...,Xn>i dla każdego parametru typu variant Xi jedną z następujących posiada: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 jest kowariantny i istnieje niejawna konwersja odwołania lub tożsamości Ai do BiXi is covariant and an implicit reference or identity conversion exists from Ai to Bi
  • Xi jest kontrawariantny i niejawne odwołanie lub istnieje konwersja tożsamości z Bi do AiXi is contravariant and an implicit reference or identity conversion exists from Bi to Ai
  • Xi jest niezależna i tożsamości istnieje konwersja z Ai do BiXi is invariant and an identity conversion exists from Ai to Bi

Interfejsy podstawoweBase interfaces

Interfejs może dziedziczyć z zero lub więcej typów interfejsów, które są nazywane jawne interfejsy podstawowe interfejsu.An interface can inherit from zero or more interface types, which are called the explicit base interfaces of the interface. Gdy interfejs ma jeden lub więcej jawne interfejsy podstawowe, następnie w deklaracji interfejsu, identyfikator interfejsu następuje dwukropek i przecinkami oddzielone listy typów interfejs podstawowy.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
    ;

Dla typu skonstruowanego interfejsu jawnego interfejsy podstawowe są utworzone przez podejmowanie deklaracje jawne interfejs podstawowy deklaracją typu ogólnego oraz zastępując dla każdego type_parameter w interfejs podstawowy Deklaracja, odpowiedni type_argument skonstruowanego typu.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.

Jawne interfejsy podstawowe interfejsu musi być co najmniej tak samo dostępna jako interfejs, sama (ograniczenia ułatwień dostępu).The explicit base interfaces of an interface must be at least as accessible as the interface itself (Accessibility constraints). Na przykład, jest to błąd kompilacji, aby określić private lub internal interfejsu w interface_base z public interfejsu.For example, it is a compile-time error to specify a private or internal interface in the interface_base of a public interface.

Jest to błąd czasu kompilacji, interfejsu bezpośrednio lub pośrednio dziedziczyć po sobie samym.It is a compile-time error for an interface to directly or indirectly inherit from itself.

Podstawowa interfejsów interfejsu są jawne interfejsy podstawowe i ich interfejsy podstawowe.The base interfaces of an interface are the explicit base interfaces and their base interfaces. Oznacza to zbiór interfejsy podstawowe jest pełne zamknięcie przechodnie jawne interfejsy podstawowe, jawne interfejsy podstawowe i tak dalej.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. Interfejs dziedziczy wszystkie elementy członkowskie jego interfejsy podstawowe.An interface inherits all members of its base interfaces. W przykładzieIn the example

interface IControl
{
    void Paint();
}

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

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

interface IComboBox: ITextBox, IListBox {}

interfejsy podstawowe z IComboBoxIControl, ITextBox, i IListBox.the base interfaces of IComboBox are IControl, ITextBox, and IListBox.

Innymi słowy IComboBox powyżej interfejs dziedziczy członków SetText i SetItems także Paint.In other words, the IComboBox interface above inherits members SetText and SetItems as well as Paint.

Każdy interfejs podstawowy interfejsu muszą być bezpieczne pod względem danych wyjściowych (bezpieczeństwa wariancji).Every base interface of an interface must be output-safe (Variance safety). Klasa lub struktura, która implementuje interfejs, dodatkowo niejawnie implementuje wszystkie interfejsy podstawowe interfejsu.A class or struct that implements an interface also implicitly implements all of the interface's base interfaces.

Treść interfejsuInterface body

Interface_body interfejsu definiuje składowych interfejsu.The interface_body of an interface defines the members of the interface.

interface_body
    : '{' interface_member_declaration* '}'
    ;

Elementy członkowskie interfejsuInterface members

Członkowie interfejsu są dziedziczone z interfejsy podstawowe elementy członkowskie i elementy członkowskie zadeklarowana przez sam interfejs.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
    ;

Deklaracja interfejsu może zadeklarować zero lub więcej elementów członkowskich.An interface declaration may declare zero or more members. Członkowie interfejs musi być metody, właściwości, zdarzeń i indeksatorów.The members of an interface must be methods, properties, events, or indexers. Interfejs nie może zawierać stałe, pola, operatory, konstruktory wystąpień, destruktorów ani typów nie może zawierać interfejs statyczne elementy członkowskie dowolnego rodzaju.An interface cannot contain constants, fields, operators, instance constructors, destructors, or types, nor can an interface contain static members of any kind.

Wszyscy członkowie interfejsu niejawnie mają dostęp publiczny.All interface members implicitly have public access. Jest to błąd kompilacji, dla deklaracji elementu członkowskiego interfejsu do uwzględnienia wszelkich modyfikatorów.It is a compile-time error for interface member declarations to include any modifiers. W szczególności członków interfejsów nie można zadeklarować za pomocą modyfikatorów abstract, public, protected, internal, private, virtual, override, lub static.In particular, interfaces members cannot be declared with the modifiers abstract, public, protected, internal, private, virtual, override, or static.

PrzykładThe 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; }
}

deklaruje interfejs, który zawiera jedną z możliwych rodzajów elementów członkowskich: Metody, właściwości, zdarzenia i indeksatora.declares an interface that contains one each of the possible kinds of members: A method, a property, an event, and an indexer.

Interface_declaration tworzy nowe miejsce do deklaracji (deklaracje), a interface_member_declarations natychmiast zawartych interface_declaration wprowadzenia nowych członków do tej deklaracji przestrzeni.An interface_declaration creates a new declaration space (Declarations), and the interface_member_declarations immediately contained by the interface_declaration introduce new members into this declaration space. Następujące reguły mają zastosowanie do interface_member_declarations:The following rules apply to interface_member_declarations:

  • Nazwa metody muszą różnić się od nazwy wszystkich właściwości i zdarzenia zadeklarowanych w tym samym interfejsie.The name of a method must differ from the names of all properties and events declared in the same interface. Ponadto, podpis (podpisów i przeciążenie) z metody muszą różnić się od podpisy wszystkich pozostałych metod zadeklarowanych w tym samym interfejsie i dwóch metod zadeklarowanych w tym samym interfejsie nie może mieć podpisów, różnią się jedynie przez ref i 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.
  • Nazwa właściwości lub zdarzenia musi się różnić od nazw innych składowych zadeklarowanych w tym samym interfejsie.The name of a property or event must differ from the names of all other members declared in the same interface.
  • Podpis indeksatora musi się różnić od podpisy innymi indeksatorami zadeklarowanych w tym samym interfejsie.The signature of an indexer must differ from the signatures of all other indexers declared in the same interface.

Dziedziczone składowe interfejsu są specjalnie nie jest częścią przestrzeni deklaracji interfejsu.The inherited members of an interface are specifically not part of the declaration space of the interface. W związku z tym interfejs może zadeklarować członka o tej samej nazwie lub podpisie, jako dziedziczonego członka.Thus, an interface is allowed to declare a member with the same name or signature as an inherited member. W takiej sytuacji interfejs pochodny element członkowski jest nazywany Ukryj składowe interfejs podstawowy.When this occurs, the derived interface member is said to hide the base interface member. Ukrywanie dziedziczonej składowej nie jest uważany za błąd, ale spowodować, że kompilator generuje ostrzeżenia.Hiding an inherited member is not considered an error, but it does cause the compiler to issue a warning. Aby pominąć to ostrzeżenie, musi zawierać deklaracji elementu członkowskiego interfejsu pochodnego new modyfikator, aby wskazać, że składowa pochodnej jest przeznaczona do Ukryj składową bazową.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. W tym temacie omówiono w dalszej ukrywanie poprzez dziedziczenie.This topic is discussed further in Hiding through inheritance.

Jeśli new modyfikator znajduje się w deklaracji, która nie ukrywa dziedziczonego członka, w tym celu jest wyświetlane ostrzeżenie.If a new modifier is included in a declaration that doesn't hide an inherited member, a warning is issued to that effect. To ostrzeżenie jest pominięty, usuwając new modyfikator.This warning is suppressed by removing the new modifier.

Należy pamiętać, że elementy członkowskie w klasie object nie są ściśle rzecz biorąc, elementy członkowskie dowolnego interfejsu (interfejsu członków).Note that the members in class object are not, strictly speaking, members of any interface (Interface members). Jednak elementy członkowskie w klasie object są dostępne za pośrednictwem wyszukać składowej w dowolny typ interfejsu (wyszukanie członka).However, the members in class object are available via member lookup in any interface type (Member lookup).

Metody interfejsuInterface methods

Metody interfejsu są deklarowane przy użyciu interface_method_declarations:Interface methods are declared using interface_method_declarations:

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

Atrybuty, Typ_wyniku, identyfikator, i formal_parameter_list deklaracji metody interfejsu mają taki sam co oznacza, jak te deklaracji metody w klasie (metody).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). Deklaracji metody interfejsu nie jest dozwolona, aby określić treści metody, a deklaracji w związku z tym zawsze kończy się średnikiem.An interface method declaration is not permitted to specify a method body, and the declaration therefore always ends with a semicolon.

Każdego typu formalnego parametru metody interfejsu muszą być bezpieczne pod względem danych wejściowych (bezpieczeństwa wariancji), i zwracanym typem musi być albo void lub bezpieczny w danych wyjściowych.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. Ponadto każdy ograniczenie typu klasy, ograniczenie typu interfejsu i ograniczenia parametru typu dowolnego typu jako parametru metody muszą być bezpieczne pod względem danych wejściowych.Furthermore, each class type constraint, interface type constraint and type parameter constraint on any type parameter of the method must be input-safe.

Te reguły upewnij się, że wszelkie kowariantny lub kontrawariantny użycia interfejsu pozostaje bezpiecznegop typu.These rules ensure that any covariant or contravariant usage of the interface remains type-safe. Na przykładFor example,

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

jest niedozwolony ponieważ użycie T jako ograniczenia parametru typu na U nie jest bezpieczna pod danych wejściowych.is illegal because the usage of T as a type parameter constraint on U is not input-safe.

To ograniczenie nie stosowanych wcześniej sytuacji będzie można naruszyć bezpieczeństwo typu w następujący sposób: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>();

To jest faktycznie wywołanie C.M<E>.This is actually a call to C.M<E>. Jednak, że wywołanie jest wymagane, aby E dziedziczyć D, więc zostałyby w tym miejscu naruszone bezpieczeństwo typów.But that call requires that E derive from D, so type safety would be violated here.

Właściwości interfejsuInterface properties

Właściwości interfejsu są deklarowane przy użyciu interface_property_declarations:Interface properties are declared using interface_property_declarations:

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

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

Atrybuty, typu, i identyfikator deklaracji właściwości interfejsu mają takie samo znaczenie jak deklaracja właściwości w klasie ( Właściwości).The attributes, type, and identifier of an interface property declaration have the same meaning as those of a property declaration in a class (Properties).

Metod dostępu w deklaracji właściwości interfejsu odpowiadają metod dostępu w deklaracji właściwości klasy (Akcesory), z tą różnicą, że treść metody dostępu musi być zawsze średnikiem.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. W związku z tym Akcesory wystarczy wskazać, czy właściwość jest odczytu i zapisu, tylko do odczytu lub tylko do zapisu.Thus, the accessors simply indicate whether the property is read-write, read-only, or write-only.

Typ właściwości interfejsu muszą być bezpieczne dane wyjściowe, jeśli ma ona metody dostępu get i muszą być bezpieczne danych wejściowych w przypadku dostępu set.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.

Zdarzenia interfejsuInterface events

Zdarzenia interfejsu są deklarowane przy użyciu interface_event_declarations:Interface events are declared using interface_event_declarations:

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

Atrybuty, typu, i identyfikator deklaracji zdarzenia interfejsu mają takie samo znaczenie jak w deklaracji zdarzenia w klasie (zdarzenia ).The attributes, type, and identifier of an interface event declaration have the same meaning as those of an event declaration in a class (Events).

Typ interfejsu zdarzenia musi być bezpieczne pod względem danych wejściowych.The type of an interface event must be input-safe.

Indeksatory interfejsówInterface indexers

Indeksatory interfejsu są deklarowane przy użyciu interface_indexer_declarations:Interface indexers are declared using interface_indexer_declarations:

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

Atrybuty, typu, i formal_parameter_list deklaracji interfejsu indeksator mają takie samo znaczenie jak deklaracja indeksatora w klasie ( Indeksatory).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).

Metod dostępu w deklaracji interfejsu indeksatora odpowiadają metod dostępu w deklaracji klasy indeksatora (indeksatory), z tą różnicą, że treść metody dostępu musi być zawsze średnikiem.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. W efekcie metod dostępu po prostu informujące o indeksatora odczytu i zapisu, tylko do odczytu lub tylko do zapisu.Thus, the accessors simply indicate whether the indexer is read-write, read-only, or write-only.

Wszystkie typy parametrów formalnych indeksatora interfejsu muszą być bezpieczne pod względem danych wejściowych.All the formal parameter types of an interface indexer must be input-safe . Ponadto wszelkie out lub ref typy parametrów formalnych również muszą być bezpieczne pod względem danych wyjściowych.In addition, any out or ref formal parameter types must also be output-safe. Należy pamiętać, że nawet out parametry są wymagane jako dane wejściowe, bezpieczne, ze względu na ograniczenie możliwości wykonywania platformy.Note that even out parameters are required to be input-safe, due to a limitation of the underlying execution platform.

Typ indeksatora interfejsu muszą być bezpieczne dane wyjściowe, jeśli ma ona metody dostępu get i muszą być bezpieczne danych wejściowych w przypadku dostępu set.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.

Dostęp do elementu członkowskiego interfejsuInterface member access

Elementy członkowskie interfejsu są dostępne za pośrednictwem dostępu do elementu członkowskiego (dostęp do elementu członkowskiego) i dostęp indeksatora (dostęp indeksatora) wyrażeń formularza I.M i I[A], gdzie I jest typem interfejsu M jest metoda, właściwość lub zdarzenie tego typu interfejsu i A to lista argumentu indeksatora.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.

Dla interfejsów, które są ściśle pojedyncze dziedziczenie (każdego interfejsu w łańcuch dziedziczenia ma dokładnie zero lub jeden interfejs podstawowy bezpośrednich), wpływ wyszukanie członka (wyszukanie członka), wywołanie metody ( Wywołań metod), a dostęp indeksatora (dostęp indeksatora) reguły są dokładnie takie same jak dla klasy i struktury: Ukryj członków więcej uzyskiwana mniej pochodnego elementów członkowskich z tej samej nazwie lub podpisie.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. Jednak dla interfejsów dziedziczenia wielokrotnego niejednoznaczności może wystąpić, gdy dwie lub więcej niepowiązanych interfejsy podstawowe zadeklarować składowych o tej samej nazwie lub podpisie.However, for multiple-inheritance interfaces, ambiguities can occur when two or more unrelated base interfaces declare members with the same name or signature. W tej sekcji przedstawiono kilka przykładów takich sytuacji.This section shows several examples of such situations. We wszystkich przypadkach ma jawnych rzutowań może służyć do rozwiązywania niejednoznaczności.In all cases, explicit casts can be used to resolve the ambiguities.

W przykładzieIn 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
    }
}

pierwsze dwie instrukcje powodują błędy czasu kompilacji, ponieważ wyszukanie członka (wyszukanie członka) z Count w IListCounter jest niejednoznaczna.the first two statements cause compile-time errors because the member lookup (Member lookup) of Count in IListCounter is ambiguous. Jak pokazano w przykładzie, niejednoznaczności został rozwiązany przez rzutowanie x do typu odpowiedniego do interfejsu podstawowego.As illustrated by the example, the ambiguity is resolved by casting x to the appropriate base interface type. Takie rzutowania mieć żadnych kosztów środowiska wykonawczego — jedynie składają się one wyświetlania wystąpienia jako mniej pochodnego typu w czasie kompilacji.Such casts have no run-time costs—they merely consist of viewing the instance as a less derived type at compile-time.

W przykładzieIn 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
    }
}

wywołanie n.Add(1) wybiera IInteger.Add , stosując zasady rozpoznawania przeciążenia Rozpoznanie przeciążenia.the invocation n.Add(1) selects IInteger.Add by applying the overload resolution rules of Overload resolution. Podobnie wywołanie n.Add(1.0) wybiera IDouble.Add.Similarly the invocation n.Add(1.0) selects IDouble.Add. Podczas wstawiania ma jawnych rzutowań, istnieje tylko jeden Release candidate metody i w związku z tym żadnych niejednoznaczności.When explicit casts are inserted, there is only one candidate method, and thus no ambiguity.

W przykładzieIn 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
    }
}

IBase.F składowa ukryta przez ILeft.F elementu członkowskiego.the IBase.F member is hidden by the ILeft.F member. Wywołanie d.F(1) wybiera w związku z tym ILeft.F, nawet jeśli IBase.F wydaje się nie być ukryte w ścieżce dostępu, który prowadzi przez 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.

Intuicyjne reguły dla ukrywanie w interfejsach dziedziczenia wielokrotnego to po prostu: Jeśli element członkowski jest ukryty w dowolnej ścieżce dostęp, jest on ukryty wszystkich ścieżek dostępu.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. Ponieważ ścieżka dostępu z IDerived do ILeft do IBase ukrywa IBase.F, należy również jest ukryty w ścieżce dostępu z IDerived do IRight do 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.

Interfejs w pełni kwalifikowanej nazwy elementów członkowskichFully qualified interface member names

Elementu członkowskiego interfejsu nazywa się czasem za jego w pełni kwalifikowana nazwa.An interface member is sometimes referred to by its fully qualified name. W pełni kwalifikowaną nazwę elementu członkowskiego interfejsu składa się z nazwy interfejsu, w którym składowa jest zadeklarowana, następuje kropka, następuje nazwa elementu członkowskiego.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. W pełni kwalifikowaną nazwę elementu członkowskiego odwołuje się do interfejsu, w którym zadeklarowany jest elementu członkowskiego.The fully qualified name of a member references the interface in which the member is declared. Na przykład biorąc pod uwagę deklaracjiFor example, given the declarations

interface IControl
{
    void Paint();
}

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

w pełni kwalifikowana nazwa Paint jest IControl.Paint i w pełni kwalifikowana nazwa SetText jest ITextBox.SetText.the fully qualified name of Paint is IControl.Paint and the fully qualified name of SetText is ITextBox.SetText.

W powyższym przykładzie nie jest możliwe do odwoływania się do Paint jako ITextBox.Paint.In the example above, it is not possible to refer to Paint as ITextBox.Paint.

Gdy interfejs jest częścią przestrzeni nazw, w pełni kwalifikowaną nazwę elementu członkowskiego interfejsu zawiera nazwę przestrzeni nazw.When an interface is part of a namespace, the fully qualified name of an interface member includes the namespace name. Na przykładFor example

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

Tutaj, w pełni kwalifikowana nazwa Clone metodą jest System.ICloneable.Clone.Here, the fully qualified name of the Clone method is System.ICloneable.Clone.

Implementacje interfejsuInterface implementations

Interfejsy mogą być wykonywane przez klas i struktur.Interfaces may be implemented by classes and structs. Aby wskazać, że klasa lub struktura bezpośrednio implementuje interfejs, identyfikator interfejsu znajduje się na liście klas bazowych, klasy lub struktury.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. Na przykład:For example:

interface ICloneable
{
    object Clone();
}

interface IComparable
{
    int CompareTo(object other);
}

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

Klasa lub struktura, która bezpośrednio implementuje interfejs także bezpośrednio implementuje wszystkie interfejsy podstawowe interfejsu niejawnie.A class or struct that directly implements an interface also directly implements all of the interface's base interfaces implicitly. Ta zasada obowiązuje, nawet jeśli w klasie lub strukturze nie jawnie wszystkie interfejsy podstawowe na liście klas bazowych.This is true even if the class or struct doesn't explicitly list all base interfaces in the base class list. Na przykład:For example:

interface IControl
{
    void Paint();
}

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

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

W tym miejscu klasy TextBox implementuje interfejsy IControl i ITextBox.Here, class TextBox implements both IControl and ITextBox.

Gdy klasa C bezpośrednio implementuje interfejs, wszystkie klasy pochodne od C umożliwiający również implementuj interfejs niejawnie.When a class C directly implements an interface, all classes derived from C also implement the interface implicitly. Interfejsy podstawowe, określonym w deklaracji klasy mogą być typami skonstruowanego interfejsu (skonstruowany typy).The base interfaces specified in a class declaration can be constructed interface types (Constructed types). Interfejs podstawowy nie może być parametrem typu samodzielnie, chociaż może pociągać za sobą parametry typu, które znajdują się w zakresie.A base interface cannot be a type parameter on its own, though it can involve the type parameters that are in scope. Poniższy kod ilustruje, jak wdrożyć i rozszerzyć typy utworzone klasy: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> {}

Interfejsy podstawowe w deklaracji klasy ogólnej musi spełniać reguły unikatowości opisanego w unikatowości implementowane interfejsy.The base interfaces of a generic class declaration must satisfy the uniqueness rule described in Uniqueness of implemented interfaces.

W jawnej implementacji elementu członkowskiegoExplicit interface member implementations

Do celów implementacja interfejsy, klasy lub struktury może deklarować implementacji elementu członkowskiego interfejsu jawnego.For purposes of implementing interfaces, a class or struct may declare explicit interface member implementations. Implementacja interfejsu jawnego członka jest deklaracji metody, właściwości, zdarzenia lub indeksatora, która odwołuje się do interfejsu w pełni kwalifikowaną nazwę elementu członkowskiego.An explicit interface member implementation is a method, property, event, or indexer declaration that references a fully qualified interface member name. Na przykładFor 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) {...}
}

W tym miejscu IDictionary<int,T>.this i IDictionary<int,T>.Add są w jawnej implementacji elementu członkowskiego.Here IDictionary<int,T>.this and IDictionary<int,T>.Add are explicit interface member implementations.

W niektórych przypadkach nazwa elementu członkowskiego interfejsu nie może być odpowiednia dla klasy implementującej, w których przypadku składowej interfejsu informacje mogą być wprowadzone przy użyciu jawną implementacją członków.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. Klasy implementującej abstrakcji pliku, na przykład, prawdopodobnie będzie implementować Close funkcja elementu członkowskiego, która obowiązuje przy zwalnianiu zasobów plików i zaimplementować Dispose metody IDisposable interfejs, za pomocą interfejsu jawnego implementacja elementu członkowskiego: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);
    }
}

Nie jest możliwe uzyskanie dostępu jawną implementacją członków przy użyciu jego w pełni kwalifikowana nazwa wywołania metody, dostęp do właściwości lub indeksatora dostępu.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. Implementacja interfejsu jawnego członka może zostać oceniony jedynie przez wystąpienie interfejsu i w takim przypadku odwołuje się po prostu jego nazwa elementu członkowskiego.An explicit interface member implementation can only be accessed through an interface instance, and is in that case referenced simply by its member name.

Jest to błąd czasu kompilacji dla jawną implementacją członków do uwzględnienia modyfikatory dostępu i jest błąd kompilacji w celu uwzględnienia modyfikatorów abstract, virtual, override, lub 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.

W jawnej implementacji elementu członkowskiego ma właściwości o różnej dostępności niż pozostałe elementy członkowskie.Explicit interface member implementations have different accessibility characteristics than other members. Ponieważ implementacji elementu członkowskiego interfejsu jawnego nigdy nie są dostępne za pośrednictwem ich w pełni kwalifikowana nazwa w wywołaniu metody lub dostęp do właściwości, są one w sensie prywatnych.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. Jednak ponieważ są one dostępne za pośrednictwem wystąpienia interfejsu, są one w sensie również publicznych.However, since they can be accessed through an interface instance, they are in a sense also public.

W jawnej implementacji elementu członkowskiego służą dwa podstawowe cele:Explicit interface member implementations serve two primary purposes:

  • Ponieważ w jawnej implementacji elementu członkowskiego nie są dostępne za pośrednictwem wystąpienia klasy lub struktury, umożliwiają one implementacji interfejsów, które mają być wykluczone z publicznego interfejsu klasy lub struktury.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. Jest to szczególnie przydatne, gdy klasa lub struktura implementuje wewnętrznego interfejsu, który jest nie interesujące użytkownika tej klasy lub struktury.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.
  • W jawnej implementacji elementu członkowskiego zezwala na Uściślanie składowych interfejsu, z tym samym podpisie.Explicit interface member implementations allow disambiguation of interface members with the same signature. Bez implementacji elementu członkowskiego interfejsu jawnego byłoby niemożliwe do klasy lub struktury mają różne implementacje interfejsu elementów członkowskich z tym samym podpisie i zwraca typ, jako jej byłyby niemożliwe do klasy lub struktury mają implementacji we wszystkich składowych interfejsu, w tym samym podpisie, ale różne typy zwracane.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.

W przypadku jawną implementacją członków był prawidłowy, klasy lub struktury należy nazwać interfejs na swojej liście klas bazowych, zawierający element, którego w pełni kwalifikowana nazwa, typ i typy parametrów dokładnie odpowiadają elementu członkowskiego interfejsu jawnego Implementacja.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. W związku z tym w następującej klasyThus, in the following class

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

Deklaracja IComparable.CompareTo powoduje błąd w czasie kompilacji, ponieważ IComparable nie znajduje się na liście klas bazowych z Shape i nie jest interfejsem podstawowy 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. Podobnie w deklaracjachLikewise, in the declarations

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

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

Deklaracja ICloneable.Clone w Ellipse powoduje błąd w czasie kompilacji, ponieważ ICloneable nie jest jawnie wymienione na liście klas bazowych z 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.

Interfejs, w którym zadeklarowano ten element członkowski musi odwoływać się w pełni kwalifikowaną nazwę elementu członkowskiego interfejsu.The fully qualified name of an interface member must reference the interface in which the member was declared. W efekcie w deklaracjachThus, 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) {...}
}

jawną implementacją członków z Paint musi być napisana jako IControl.Paint.the explicit interface member implementation of Paint must be written as IControl.Paint.

Unikatowość implementowanych interfejsówUniqueness of implemented interfaces

Interfejsy implementowane przez deklarację typu ogólnego musi pozostać unikatowe dla wszystkich możliwych typów skonstruowany.The interfaces implemented by a generic type declaration must remain unique for all possible constructed types. Bez tej reguły byłoby niemożliwe do należy określić poprawną metodę do wywołania dla niektórych typów skonstruowany.Without this rule, it would be impossible to determine the correct method to call for certain constructed types. Na przykład załóżmy, że zezwolono deklaracji klasy ogólnej do zapisania w następujący sposób: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() {...}
}

Była to dozwolone, byłoby niemożliwe do należy określić które kodu do wykonania w następujących przypadkach: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();

Aby ustalić, czy lista interfejsu deklaracją typu ogólnego jest prawidłowy, wykonywane są następujące czynności:To determine if the interface list of a generic type declaration is valid, the following steps are performed:

  • Pozwól L się na liście interfejsów bezpośrednio określone w ogólnej klasy, struktury lub interfejsu deklaracji C.Let L be the list of interfaces directly specified in a generic class, struct, or interface declaration C.
  • Dodaj do L podstawowa dowolne interfejsy interfejsów, które są już w L.Add to L any base interfaces of the interfaces already in L.
  • Usuń duplikaty z L.Remove any duplicates from L.
  • Jeśli wszystkie możliwe zbudowany typ utworzone na podstawie C będzie po argumentów typu są zastępowane do L, spowodować, że dwa interfejsy w L być identyczne i następnie deklaracji C jest nieprawidłowy.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. Deklaracje ograniczenia nie są uwzględniane podczas określania wszystkie możliwe typy utworzone.Constraint declarations are not considered when determining all possible constructed types.

W deklaracji klasy X powyżej listy interfejsu L składa się z I<U> i I<V>.In the class declaration X above, the interface list L consists of I<U> and I<V>. Deklaracja jest nieprawidłowy, ponieważ skonstruowany dowolnego typu za pomocą U i V są tego samego typu spowodowałoby te dwa interfejsy być identyczne typy.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.

Możliwe jest, określonych na dziedziczenie różnych poziomach w celu ujednolicenie interfejsów: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() {...}
}

Mimo że ten kod jest prawidłowy Derived<U,V> implementuje interfejsy I<U> i I<V>.This code is valid even though Derived<U,V> implements both I<U> and I<V>. KodThe code

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

wywołuje metodę w Derived, ponieważ Derived<int,int> w praktyce oznacza ponowne wdrożenie I<int> (interfejs ponowną implementację).invokes the method in Derived, since Derived<int,int> effectively re-implements I<int> (Interface re-implementation).

Implementacja metody ogólneImplementation of generic methods

Gdy metody ogólnej niejawnie implementuje metodę interfejsu ograniczeń dla każdego parametr typu metody musi być równoważna w obu deklaracjach (po dowolny typ interfejsu parametry są zastępowane odpowiednie argumenty typu), gdzie — metoda Parametry typu są identyfikowane przez numer porządkowy pozycji, od lewej do prawej.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.

Gdy metody ogólnej jawnie implementuje metodę interfejsu, jednak bez ograniczeń są dozwolone dla metody wykonawcze.When a generic method explicitly implements an interface method, however, no constraints are allowed on the implementing method. Zamiast tego ograniczenia są dziedziczone z metody interfejsuInstead, 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
}

Metoda C.F<T> niejawnie implementuje I<object,C,string>.F<T>.The method C.F<T> implicitly implements I<object,C,string>.F<T>. W tym przypadku C.F<T> jest nie wymagane (ani nie dozwolone) do określenia ograniczenie T:object ponieważ object niejawne ograniczenia dotyczące wszystkich parametrów typu.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. Metoda C.G<T> niejawnie implementuje I<object,C,string>.G<T> ponieważ ograniczenia odpowiadają w interfejsie, po zastąpieniu parametry typu interface odpowiednie argumenty typu.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. Ograniczenie dla metody C.H<T> występuje błąd, ponieważ zamknięte typy (string w tym przypadku) nie może być używane jako warunki ograniczające.The constraint for method C.H<T> is an error because sealed types (string in this case) cannot be used as constraints. Pominięcie tego ograniczenia będą również błąd, ponieważ ograniczenia implementacje metod interfejsu niejawne muszą być zgodne.Omitting the constraint would also be an error since constraints of implicit interface method implementations are required to match. W związku z tym, nie jest możliwe implementować niejawnie I<object,C,string>.H<T>.Thus, it is impossible to implicitly implement I<object,C,string>.H<T>. Ta metoda interfejsu można zaimplementować tylko przy użyciu jawną implementacją członków: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);
    }
}

W tym przykładzie jawną implementacją członków wywołuje metodę publiczną o ściśle słabszy ograniczenia.In this example, the explicit interface member implementation invokes a public method having strictly weaker constraints. Należy pamiętać, że przypisanie z t do s jest prawidłowy, ponieważ T dziedziczy z ograniczeniem T:string, mimo że to ograniczenie nie ma można wyrazić w kodzie źródłowym.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.

Mapowanie interfejsuInterface mapping

Klasy lub struktury, należy podać implementacji wszystkich członków interfejsów, które są wymienione na liście klas bazowych, klasy lub struktury.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. Proces trwa lokalizowanie implementacji członków interfejsów w implementujące klasy lub struktury jest znany jako mapowania interfejsu.The process of locating implementations of interface members in an implementing class or struct is known as interface mapping.

Mapowanie interfejsu dla klasy lub struktury C lokalizuje implementację dla każdego elementu członkowskiego każdy interfejs określony na liście klas bazowych z 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. Implementacja interfejsu określonego elementu członkowskiego I.M, gdzie I interfejs, w którym element członkowski M zadeklarowano, jest określana przez badanie każda klasa lub struktura S, począwszy od C i Powtarzanie dla każdego kolejnych klasę bazową C, dopóki nie znajduje się dopasowania: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:

  • Jeśli S zawiera deklarację jawnej implementacji elementu członkowskiego, który odpowiada I i M, ten element członkowski jest implementacja 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.
  • W przeciwnym razie, jeśli S zawiera deklarację niestatycznej składowej publiczny, który odpowiada M, ten element członkowski jest implementacja 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. Jeśli więcej niż jeden element członkowski są zgodne, jest nieokreślona składowej, która jest implementacją I.M.If more than one member matches, it is unspecified which member is the implementation of I.M. Taka sytuacja może wystąpić tylko, jeśli S jest skonstruowanego typu, w której dwa elementy członkowskie zadeklarowane w typie ogólnym mają różnych podpisów, ale argumentów typu należy ich podpisy identyczne.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.

Występuje błąd kompilacji, jeśli implementacje nie można znaleźć dla wszystkich elementów członkowskich wszystkie interfejsy określone na liście klas bazowych, z 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. Należy pamiętać, że Członkowie interfejsu obejmują te elementy członkowskie, które są dziedziczone z interfejsy podstawowe.Note that the members of an interface include those members that are inherited from base interfaces.

Na potrzeby mapowania interfejsu, element członkowski klasy A pasuje do elementu członkowskiego interfejsu B po:For purposes of interface mapping, a class member A matches an interface member B when:

  • A i B są metody i nazwę typu, a list parametrów formalnych A i B są identyczne.A and B are methods, and the name, type, and formal parameter lists of A and B are identical.
  • A i B są właściwości, nazwę i typ A i B są identyczne, i A ma tej samej metody dostępu jako B (A może mieć dodatkowe metody dostępu, jeśli nie jest interfejsem jawne implementacja elementu członkowskiego).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 i B są zdarzenia oraz nazwę i typ A i B są identyczne.A and B are events, and the name and type of A and B are identical.
  • A i B indeksatorów, typ i listy parametrów formalnych A i B są identyczne, i A ma tej samej metody dostępu jako B (A mają dodatkowe metody dostępu, jeśli nie jest dozwolone jawną implementacją członków).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).

Dostępne są następujące istotne implikacje algorytm mapowania interfejsu:Notable implications of the interface mapping algorithm are:

  • W jawnej implementacji elementu członkowskiego mają pierwszeństwo przed innych członków w tej samej klasie lub strukturze podczas określania składowej klasy lub struktury, która implementuje składową interfejsu.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.
  • Niepubliczne ani statyczne elementy członkowskie uczestniczyć w mapowania interfejsu.Neither non-public nor static members participate in interface mapping.

W przykładzieIn the example

interface ICloneable
{
    object Clone();
}

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

ICloneable.Clone członkiem C staje się implementacja Clone w ICloneable ponieważ implementacji elementu członkowskiego interfejsu jawnego mają pierwszeństwo przed innymi członkami.the ICloneable.Clone member of C becomes the implementation of Clone in ICloneable because explicit interface member implementations take precedence over other members.

Jeśli klasa lub struktura implementuje dwa lub więcej interfejsów zawierający element członkowski o takiej samej nazwie, typie i typy parametrów, jest możliwe mapowanie każdego z tych składowych interfejsu na jeden element członkowski klasy lub struktury.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. Na przykładFor example

interface IControl
{
    void Paint();
}

interface IForm
{
    void Paint();
}

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

W tym miejscu Paint obu metod IControl i IForm są mapowane na Paint method in Class metoda Page.Here, the Paint methods of both IControl and IForm are mapped onto the Paint method in Page. Oczywiście również istnieje możliwość mają oddzielne interfejsu jawnego implementacji elementu członkowskiego dla obu metod.It is of course also possible to have separate explicit interface member implementations for the two methods.

Jeśli klasa lub struktura implementuje interfejs, który zawiera ukryte elementy członkowskie, niektóre elementy członkowskie niekoniecznie musi być implementowany przez implementacji elementu członkowskiego interfejsu jawnego.If a class or struct implements an interface that contains hidden members, then some members must necessarily be implemented through explicit interface member implementations. Na przykładFor example

interface IBase
{
    int P { get; }
}

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

Implementację tego interfejsu wymaga co najmniej jedną jawną implementacją członków, a następnie może wykonać jedną z następujących formAn 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() {...}
}

Gdy klasa implementuje wiele interfejsów, które mają ten sam interfejs podstawowy, może istnieć tylko jedna implementacja interfejs podstawowy.When a class implements multiple interfaces that have the same base interface, there can be only one implementation of the base interface. W przykładzieIn 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) {...}
}

nie jest możliwe mieć osobne implementacje dla IControl o nazwie na liście klas bazowych IControl dziedziczone przez ITextBoxi IControl dziedziczone przez IListBox.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. W rzeczywistości nie są używane osobne tożsamości dla tych interfejsów.Indeed, there is no notion of a separate identity for these interfaces. Zamiast implementacje ITextBox i IListBox udostępnianie tego samego wdrożenia IControl, i ComboBox uznaje się wystarczy do zaimplementowania trzy interfejsy IControl, ITextBox, i 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.

Elementy członkowskie klasy bazowej uczestniczyć w mapowania interfejsu.The members of a base class participate in interface mapping. W przykładzieIn the example

interface Interface1
{
    void F();
}

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

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

Metoda F w Class1 jest używany w Class2przez implementację Interface1.the method F in Class1 is used in Class2's implementation of Interface1.

Dziedziczenie implementacji interfejsuInterface implementation inheritance

Klasa dziedziczy wszystkie implementacje interfejsu udostępniane przez jej klas podstawowych.A class inherits all interface implementations provided by its base classes.

Bez jawnie ponownej implementacji interfejsu klasy pochodnej nie może w żaden sposób zmieniać mapowania interfejs dziedziczy jej klas podstawowych.Without explicitly re-implementing an interface, a derived class cannot in any way alter the interface mappings it inherits from its base classes. Na przykład w deklaracjiFor example, in the declarations

interface IControl
{
    void Paint();
}

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

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

Paint method in Class metoda TextBox ukrywa Paint method in Class metoda Control, ale nie zmienia mapowania Control.Paint na IControl.Painti zwraca Paint za pośrednictwem klasy będzie wystąpień i wystąpienia interfejsu ma następujące skutkithe 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();

Jednak gdy metody interfejsu jest mapowana na wirtualnej metody w klasie, jest możliwe dla klasy pochodne, aby przesłonić metodę wirtualną i zmień implementację interfejsu.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. Na przykład poprawiania deklaracje powyżej doFor example, rewriting the declarations above to

interface IControl
{
    void Paint();
}

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

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

teraz będzie można zauważyć następujące efektythe 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();

Ponieważ implementacji elementu członkowskiego interfejsu jawnego nie może być zadeklarowana wirtualnego, nie jest możliwe zastąpienie jawną implementacją członków.Since explicit interface member implementations cannot be declared virtual, it is not possible to override an explicit interface member implementation. Jednak go nadaje się doskonale do jawną implementacją członków do wywoływania innej metody i czy innej metody mogą być deklarowane wirtualnego Aby zezwolić na pochodne klasy, aby go zastąpić.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. Na przykładFor example

interface IControl
{
    void Paint();
}

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

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

W tym miejscu klasy pochodne Control można specjalizować wykonania IControl.Paint przez zastąpienie PaintControl metody.Here, classes derived from Control can specialize the implementation of IControl.Paint by overriding the PaintControl method.

Ponowna implementacja interfejsuInterface re-implementation

Klasę, która dziedziczy implementację interfejsu jest dozwolona na ponownego zaimplementowania interfejsu, umieszczając je na liście klas bazowych.A class that inherits an interface implementation is permitted to re-implement the interface by including it in the base class list.

Ponowna implementacja interfejsu jest zgodna dokładnie tego samego interfejsu reguły mapowania jako początkowej implementacji interfejsu.A re-implementation of an interface follows exactly the same interface mapping rules as an initial implementation of an interface. W efekcie mapowanie dziedziczony interfejs nie ma wpływu na mapowania interfejsu ustanowione dla ponowna implementacja interfejsu.Thus, the inherited interface mapping has no effect whatsoever on the interface mapping established for the re-implementation of the interface. Na przykład w deklaracjiFor example, in the declarations

interface IControl
{
    void Paint();
}

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

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

fakt, Control mapuje IControl.Paint na Control.IControl.Paint nie ma wpływu na ponowną implementację w MyControl, mapująca IControl.Paint na 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.

Dziedziczone członka publicznego deklaracje i jawne dziedziczonego elementu członkowskiego, deklaracje uczestniczyć w trakcie mapowania interfejsu ponownie implementowane interfejsy.Inherited public member declarations and inherited explicit interface member declarations participate in the interface mapping process for re-implemented interfaces. Na przykładFor 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() {}
}

Tutaj, implementacja IMethods w Derived mapuje metod interfejsu na Derived.F, Base.IMethods.G, Derived.IMethods.H, i 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.

Gdy klasa implementuje interfejs go niejawnie implementuje również wszystkie interfejsy podstawowe tego interfejsu.When a class implements an interface, it implicitly also implements all of that interface's base interfaces. Podobnie, ponowna implementacja interfejsu jest również niejawnie ponowną implementację wszystkich interfejsów, interfejsy podstawowe.Likewise, a re-implementation of an interface is also implicitly a re-implementation of all of the interface's base interfaces. Na przykładFor 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() {...}
}

Tutaj, ponowną implementację elementu IDerived ponownie implementuje również IBase, mapowanie IBase.F na D.F.Here, the re-implementation of IDerived also re-implements IBase, mapping IBase.F onto D.F.

Klasy abstrakcyjne i interfejsyAbstract classes and interfaces

Takich jak klasy nieabstrakcyjnej klasy abstrakcyjnej muszą dostarczać implementacje, wszystkich elementów członkowskich interfejsów, które są wymienione na liście klas bazowych, klasy.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. Jednak klasy abstrakcyjnej jest dozwolone metody interfejsu na metody abstrakcyjne mapowania.However, an abstract class is permitted to map interface methods onto abstract methods. Na przykładFor example

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

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

Tutaj, implementacja IMethods mapuje F i G na metody abstrakcyjne, która musi zostać zastąpiona w nieabstrakcyjnej klasy, które wynikają z 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.

Należy pamiętać, że implementacji elementu członkowskiego interfejsu jawnego nie może być abstrakcyjny, ale implementacji elementu członkowskiego interfejsu jawnego oczywiście są dozwolone do wywołania metody abstrakcyjne.Note that explicit interface member implementations cannot be abstract, but explicit interface member implementations are of course permitted to call abstract methods. Na przykładFor 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();
}

Tutaj, klasy nieabstrakcyjnej, które wynikają z C byłoby potrzebnego do zastąpienia FF i GG, zapewniając w ten sposób wykonania rzeczywistego IMethods.Here, non-abstract classes that derive from C would be required to override FF and GG, thus providing the actual implementation of IMethods.