介面Interfaces

介面定義合約。An interface defines a contract. 類別或結構實作介面必須遵守其合約。A class or struct that implements an interface must adhere to its contract. 介面可以繼承自多個基底介面,以及類別或結構可以實作多個介面。An interface may inherit from multiple base interfaces, and a class or struct may implement multiple interfaces.

介面可以包含方法、 屬性、 事件和索引子。Interfaces can contain methods, properties, events, and indexers. 介面本身不提供它所定義之成員的實作。The interface itself does not provide implementations for the members that it defines. 介面只會指定必須提供的類別或結構實作介面成員。The interface merely specifies the members that must be supplied by classes or structs that implement the interface.

介面宣告Interface declarations

Interface_declarationtype_declaration (型別宣告),宣告了新的介面型別。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組成的一組選擇性屬性(屬性),後面接著一組選擇性的interface_modifiers (介面修飾詞),後面接著選擇性partial修飾詞,後面接著關鍵字interface識別碼可命名介面後面接著選擇性variant_type_parameter_list規格 (Variant 類型參數清單),後面接著選擇性interface_base規格 (的基底介面),後面接著選擇性type_parameter_constraints_clauses 規格 (類型參數條件約束)後面接著interface_body (介面主體),或者後面接著一個分號。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.

介面修飾詞Interface modifiers

Interface_declaration可以選擇性地包含一連串的介面修飾詞:An interface_declaration may optionally include a sequence of interface modifiers:

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

它是在 interface 宣告中出現多次相同的修飾詞的編譯時期錯誤。It is a compile-time error for the same modifier to appear multiple times in an interface declaration.

new修飾詞只能在類別內定義的介面上。The new modifier is only permitted on interfaces defined within a class. 它會指定介面會隱藏繼承的成員,以相同的名稱,如中所述的新修飾詞It specifies that the interface hides an inherited member by the same name, as described in The new modifier.

publicprotectedinternal,和private修飾詞控制介面的存取範圍。The public, protected, internal, and private modifiers control the accessibility of the interface. 根據介面宣告發生所在的內容,只有部分這些修飾詞可能會允許 (宣告存取範圍)。Depending on the context in which the interface declaration occurs, only some of these modifiers may be permitted (Declared accessibility).

Partial 修飾詞Partial modifier

partial修飾詞表示這interface_declaration是部分的型別宣告。The partial modifier indicates that this interface_declaration is a partial type declaration. 在封入命名空間或類型宣告同名的多個部分的介面宣告結合構成一個介面宣告,下列規則中指定部分型別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.

Variant 類型參數清單Variant type parameter lists

Variant 類型參數清單只能出現在介面和委派類型。Variant type parameter lists can only occur on interface and delegate types. 從一般的差異type_parameter_lists 是選擇性variance_annotation上每個類型參數。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'
    ;

如果變異數附註out,該型別參數要covariantIf the variance annotation is out, the type parameter is said to be covariant. 如果變異數附註in,該型別參數要contravariantIf the variance annotation is in, the type parameter is said to be contravariant. 如果沒有任何變異數附註,該型別參數要非變異If there is no variance annotation, the type parameter is said to be invariant.

在範例In the example

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

X 是 covariant,Y是 contravariant 和Z為非變異。X is covariant, Y is contravariant and Z is invariant.

變異數的安全Variance safety

類型參數清單中的類型的變異數附註的相符項目會限制型別可能會發生型別宣告內的位置。The occurrence of variance annotations in the type parameter list of a type restricts the places where types can occur within the type declaration.

型別T輸出 unsafe如果下列其中一種保留:A type T is output-unsafe if one of the following holds:

  • T 為 contravariant 類型參數。T is a contravariant type parameter
  • T 是輸出不安全的項目類型的陣列類型T is an array type with an output-unsafe element type
  • T 是介面或委派的型別S<A1,...,Ak>建構自泛型型別的S<X1,...,Xk>至少一個 whereAi下列其中一種保留: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 共變性或非變異值和Ai輸出不安全。Xi is covariant or invariant and Ai is output-unsafe.
    • Xi 逆變性或非變異值和Ai是輸入安全。Xi is contravariant or invariant and Ai is input-safe.

型別T輸入 unsafe如果下列其中一種保留:A type T is input-unsafe if one of the following holds:

  • T 為 covariant 類型參數。T is a covariant type parameter
  • T 是不安全的輸入項目類型的陣列類型T is an array type with an input-unsafe element type
  • T 是介面或委派的型別S<A1,...,Ak>建構自泛型型別的S<X1,...,Xk>至少一個 whereAi下列其中一種保留: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 共變性或非變異值和Ai輸入不安全。Xi is covariant or invariant and Ai is input-unsafe.
    • Xi 逆變性或非變異值和Ai輸出不安全。Xi is contravariant or invariant and Ai is output-unsafe.

直接易懂的方式,輸出不安全的型別中的輸出位置,禁止使用,並禁止到輸入位置的輸入不安全的類型。Intuitively, an output-unsafe type is prohibited in an output position, and an input-unsafe type is prohibited in an input position.

型別是輸出安全如果不是輸出不安全,並輸入安全如果不是輸入不安全。A type is output-safe if it is not output-unsafe, and input-safe if it is not input-unsafe.

變異數轉換Variance conversion

變異數附註的目的是提供較寬鬆 (但仍型別安全) 轉換成介面和委派類型。The purpose of variance annotations is to provide for more lenient (but still type safe) conversions to interface and delegate types. 這個最後的隱含定義 (隱含轉換) 和明確轉換 (明確轉換) 讓使用變異數可轉換性,其定義,如下所示的概念: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:

型別T<A1,...,An>可轉換變異數的型別T<B1,...,Bn>如果T介面或委派型別宣告具有 variant 類型參數T<X1,...,Xn>,和每個 variant 類型參數Xi下列其中之一保留: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 是 covariant,且是隱含的參考或識別轉換從AiBiXi is covariant and an implicit reference or identity conversion exists from Ai to Bi
  • Xi 而且遠端系統 contravariant 的隱含參考或識別轉換存在從BiAiXi is contravariant and an implicit reference or identity conversion exists from Bi to Ai
  • Xi 是不區分及身分識別轉換存在從AiBiXi is invariant and an identity conversion exists from Ai to Bi

基底介面Base interfaces

介面可以繼承自零或多個介面型別,稱為明確的基底介面的介面。An interface can inherit from zero or more interface types, which are called the explicit base interfaces of the interface. 當介面有一或多個明確的基底介面時,該介面,宣告中的介面識別碼接著冒號和逗號分隔的基底介面型別清單。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
    ;

建構的介面類型,明確的基底介面明確的基底介面宣告的泛型型別宣告,並取代,每個形成type_parameter基底介面中宣告對應type_argument建構的類型。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.

明確的基底介面的介面必須至少像一樣地存取介面本身 (協助工具的條件約束)。The explicit base interfaces of an interface must be at least as accessible as the interface itself (Accessibility constraints). 比方說,它是指定的編譯時期錯誤private或是internal介面中interface_basepublic介面。For example, it is a compile-time error to specify a private or internal interface in the interface_base of a public interface.

它是介面,以直接或間接繼承自它自己的編譯時期錯誤。It is a compile-time error for an interface to directly or indirectly inherit from itself.

的基底介面介面是明確的基底介面和其基底介面。The base interfaces of an interface are the explicit base interfaces and their base interfaces. 換句話說,基底介面的集合會是完整的可轉移關閉的明確的基底介面,其明確的基底介面,以及等等。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. 介面會繼承其基底介面的所有成員。An interface inherits all members of its base interfaces. 在範例In the example

interface IControl
{
    void Paint();
}

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

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

interface IComboBox: ITextBox, IListBox {}

基底介面IComboBoxIControlITextBox,和IListBoxthe base interfaces of IComboBox are IControl, ITextBox, and IListBox.

亦即IComboBox上述介面繼承成員SetTextSetItems以及PaintIn other words, the IComboBox interface above inherits members SetText and SetItems as well as Paint.

介面的每個基底介面都必須是輸出安全 (變異數安全)。Every base interface of an interface must be output-safe (Variance safety). 類別或結構也會隱含地實作介面會實作所有介面的基底介面。A class or struct that implements an interface also implicitly implements all of the interface's base interfaces.

介面主體內Interface body

Interface_body介面會定義介面的成員。The interface_body of an interface defines the members of the interface.

interface_body
    : '{' interface_member_declaration* '}'
    ;

介面成員Interface members

介面的成員會繼承自基底介面的成員,介面本身所宣告的成員。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
    ;

介面宣告可以宣告為零或多個成員。An interface declaration may declare zero or more members. 介面成員必須是方法、 屬性、 事件或索引子。The members of an interface must be methods, properties, events, or indexers. 介面不能包含常數、 欄位、 運算子、 執行個體建構函式、 解構函式或類型,也不介面可以包含任何類型的靜態成員。An interface cannot contain constants, fields, operators, instance constructors, destructors, or types, nor can an interface contain static members of any kind.

所有介面成員以隱含方式都具有公用存取。All interface members implicitly have public access. 它是介面成員宣告,包括任何修飾詞的編譯時期錯誤。It is a compile-time error for interface member declarations to include any modifiers. 特別是,介面成員不可以宣告和修飾詞abstractpublicprotectedinternalprivatevirtualoverride,或staticIn particular, interfaces members cannot be declared with the modifiers abstract, public, protected, internal, private, virtual, override, or static.

此範例The 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; }
}

宣告介面,包含其中每個可能的成員種類:方法、 屬性、 事件和索引子。declares an interface that contains one each of the possible kinds of members: A method, a property, an event, and an indexer.

Interface_declaration建立新的宣告空間 (宣告),而interface_member_declaration立即包含sinterface_declaration這個宣告空間中引入新的成員。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. 下列規則適用於interface_member_declarations:The following rules apply to interface_member_declarations:

  • 方法的名稱必須與不同的所有屬性和事件在相同的介面中宣告的名稱。The name of a method must differ from the names of all properties and events declared in the same interface. 此外,簽章 (簽章和多載) 的方法必須與相同的介面中宣告的所有其他方法的簽章不同,在相同的介面中宣告的兩種方法可能沒有簽章,差異在於完全refoutIn 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.
  • 屬性或事件的名稱必須與相同介面中宣告的所有其他成員的名稱不同。The name of a property or event must differ from the names of all other members declared in the same interface.
  • 索引子的簽章必須與相同介面中所宣告之其他所有索引子的簽章不同。The signature of an indexer must differ from the signatures of all other indexers declared in the same interface.

介面的繼承的成員是特別不屬於介面的宣告空間的一部分。The inherited members of an interface are specifically not part of the declaration space of the interface. 因此,介面可以宣告具有相同的名稱或簽章的成員,做為繼承的成員。Thus, an interface is allowed to declare a member with the same name or signature as an inherited member. 當發生這種情況時,衍生的介面成員即隱藏基底介面成員。When this occurs, the derived interface member is said to hide the base interface member. 隱藏繼承的成員不被視為錯誤,但會造成編譯器將發出警告。Hiding an inherited member is not considered an error, but it does cause the compiler to issue a warning. 若要隱藏警告,衍生的介面成員的宣告必須包含new修飾詞來表示衍生的成員要隱藏基底的成員。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. 本主題會討論中進一步經由繼承隱藏This topic is discussed further in Hiding through inheritance.

如果new修飾詞加入的宣告,也不會隱藏繼承的成員,來指出發出警告。If a new modifier is included in a declaration that doesn't hide an inherited member, a warning is issued to that effect. 藉由移除隱藏這個警告new修飾詞。This warning is suppressed by removing the new modifier.

請注意,在類別成員object則不會,嚴格地說,任何介面的成員 (介面成員)。Note that the members in class object are not, strictly speaking, members of any interface (Interface members). 不過,在類別成員object可透過任何介面類型中進行成員查詢 (成員查閱)。However, the members in class object are available via member lookup in any interface type (Member lookup).

介面方法Interface methods

介面方法使用宣告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* ';'
    ;

屬性return_type識別碼,以及formal_parameter_list的介面方法宣告都具有相同這表示的類別中的方法宣告 (方法)。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). 若要指定方法的主體中,不允許介面方法宣告,並宣告因此一律會以分號結束。An interface method declaration is not permitted to specify a method body, and the declaration therefore always ends with a semicolon.

介面方法的每個型式參數類型必須是輸入安全 (變異數安全),而且傳回型別必須是void或輸出安全。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. 此外,每個類別類型條件約束、 介面類型條件約束和方法的任何型別參數的類型參數條件約束必須是輸入安全。Furthermore, each class type constraint, interface type constraint and type parameter constraint on any type parameter of the method must be input-safe.

這些規則確保任何 covariant 或 contravariant 的介面的使用方式會保留型別安全。These rules ensure that any covariant or contravariant usage of the interface remains type-safe. 例如,套用至物件的For example,

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

不合法因為的使用方式T的型別參數條件約束為U不是輸入安全。is illegal because the usage of T as a type parameter constraint on U is not input-safe.

這項限制已不存在有可能違反類型安全,以下列方式: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>();

這是實際的呼叫C.M<E>This is actually a call to C.M<E>. 但是這種呼叫需要E衍生自D,因此這裡違反類型安全。But that call requires that E derive from D, so type safety would be violated here.

介面內容Interface properties

介面屬性使用宣告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' ';'
    ;

屬性型別,並識別碼介面屬性宣告的類別中有意義的屬性宣告相同 (屬性)。The attributes, type, and identifier of an interface property declaration have the same meaning as those of a property declaration in a class (Properties).

介面屬性宣告的存取子對應的類別屬性宣告存取子 (存取子),不同之處在於存取子主體必須是分號。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. 因此,存取子只是指出屬性是讀寫、 唯讀或唯寫。Thus, the accessors simply indicate whether the property is read-write, read-only, or write-only.

介面屬性的類型必須是輸出-安全,如果沒有 get 存取子,以及必須輸入為安全,如果沒有 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.

介面事件Interface events

使用宣告介面事件interface_event_declarations:Interface events are declared using interface_event_declarations:

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

屬性型別,並識別碼介面事件宣告的類別中有相同的意義相同的事件宣告 (事件).The attributes, type, and identifier of an interface event declaration have the same meaning as those of an event declaration in a class (Events).

介面事件的型別必須輸入為安全。The type of an interface event must be input-safe.

介面索引子Interface indexers

使用宣告介面索引子interface_indexer_declarations:Interface indexers are declared using interface_indexer_declarations:

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

屬性型別,並formal_parameter_list介面索引子宣告的有意義相同的索引子宣告中的類別 (索引子)。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).

介面索引子宣告的存取子對應的類別索引子宣告存取子 (索引子),不同之處在於存取子主體必須是分號。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. 因此,存取子只是表示索引子是讀寫、 唯讀或唯寫。Thus, the accessors simply indicate whether the indexer is read-write, read-only, or write-only.

介面索引子的型式參數類型必須是輸入安全。All the formal parameter types of an interface indexer must be input-safe . 此外,任何outref型式參數類型必須也是輸出安全。In addition, any out or ref formal parameter types must also be output-safe. 請注意,即使out參數必須是輸入安全,因為基礎執行平台的限制。Note that even out parameters are required to be input-safe, due to a limitation of the underlying execution platform.

介面索引子的型別必須是輸出-安全,如果沒有 get 存取子,以及必須輸入為安全,如果沒有 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.

介面成員存取Interface member access

成員存取透過存取介面成員 (成員存取) 和索引子存取 (索引子存取) 形式的運算式I.MI[A],其中I介面類型時,M是方法、 屬性或事件,該介面型別,以及A是索引子引數清單。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.

絕對的介面的單一繼承 (每個介面繼承鏈結中的有剛好零個或一個直接的基底介面)、 成員查詢的影響 (成員查閱),方法引動過程 (方法引動過程),和索引子存取 (索引子存取) 規則並完全與類別和結構相同:更多衍生成員隱藏較少衍生的成員具有相同名稱或簽章。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. 不過,如多重繼承的介面,可能會發生模稜兩可,若有兩個或多個不相關的基底介面宣告具有相同的名稱或簽章的成員。However, for multiple-inheritance interfaces, ambiguities can occur when two or more unrelated base interfaces declare members with the same name or signature. 本節說明幾個範例,這種情況。This section shows several examples of such situations. 在所有情況下,明確轉換 (cast) 可用來解決模稜兩可。In all cases, explicit casts can be used to resolve the ambiguities.

在範例In 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
    }
}

前兩個陳述式會造成編譯時期錯誤,因為成員查閱 (成員查閱) 的CountIListCounter模稜兩可。the first two statements cause compile-time errors because the member lookup (Member lookup) of Count in IListCounter is ambiguous. 如範例所示,透過轉型來解決模稜兩可x成適當的基底介面型別。As illustrated by the example, the ambiguity is resolved by casting x to the appropriate base interface type. 這類轉換不需要執行階段成本 — 它們只包含做為衍生程度更小的類型在編譯時期檢視的執行個體。Such casts have no run-time costs—they merely consist of viewing the instance as a less derived type at compile-time.

在範例In 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
    }
}

引動過程n.Add(1)選取IInteger.Add藉由套用的多載解析規則多載解析the invocation n.Add(1) selects IInteger.Add by applying the overload resolution rules of Overload resolution. 同樣的引動過程n.Add(1.0)選取IDouble.AddSimilarly the invocation n.Add(1.0) selects IDouble.Add. 當插入明確的轉型時,是只有一個候選項目方法,並因此沒有模稜兩可。When explicit casts are inserted, there is only one candidate method, and thus no ambiguity.

在範例In 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藉由隱藏成員ILeft.F成員。the IBase.F member is hidden by the ILeft.F member. 引動過程d.F(1)因此會選取ILeft.F,即使IBase.F似乎不會逐步引導的存取路徑中隱藏IRightThe 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.

多重繼承的介面中隱藏的直覺式規則只是這個:如果成員隱藏的任何存取路徑中,它會隱藏所有的存取路徑中。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. 因為存取路徑,從IDerivedILeftIBase隱藏IBase.F,從的存取路徑中的成員也在隱藏IDerivedIRightIBaseBecause 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

介面成員有時是由其完整限定的名稱An interface member is sometimes referred to by its fully qualified name. 介面成員的完整的名稱是由在其中成員是宣告,後面接著一個點,再加上該成員名稱的介面名稱所組成。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. 成員的完整限定的名稱參考該成員所宣告的介面。The fully qualified name of a member references the interface in which the member is declared. 例如,假設宣告For example, given the declarations

interface IControl
{
    void Paint();
}

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

完整限定的名稱PaintIControl.Paint和 完整格式的名稱SetTextITextBox.SetTextthe fully qualified name of Paint is IControl.Paint and the fully qualified name of SetText is ITextBox.SetText.

在上述範例中,它不可以參考Paint做為ITextBox.PaintIn the example above, it is not possible to refer to Paint as ITextBox.Paint.

命名空間的一部分介面時,介面成員的完整的名稱包括命名空間名稱。When an interface is part of a namespace, the fully qualified name of an interface member includes the namespace name. 例如For example

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

這裡,完整限定的名稱Clone方法是System.ICloneable.CloneHere, the fully qualified name of the Clone method is System.ICloneable.Clone.

介面實作Interface implementations

可由類別和結構實作介面。Interfaces may be implemented by classes and structs. 若要表示類別或結構直接實作的介面,基底類別清單的類別或結構中包含的介面識別項。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. 例如: For example:

interface ICloneable
{
    object Clone();
}

interface IComparable
{
    int CompareTo(object other);
}

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

類別或結構,直接也可以直接實作的介面會實作所有介面的基底介面的隱含。A class or struct that directly implements an interface also directly implements all of the interface's base interfaces implicitly. 這是 true,即使類別或結構並未明確列出基底類別清單中的所有基底介面。This is true even if the class or struct doesn't explicitly list all base interfaces in the base class list. 例如:For example:

interface IControl
{
    void Paint();
}

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

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

在這裡,類別TextBox會實作IControlITextBoxHere, class TextBox implements both IControl and ITextBox.

當類別C直接實作一個介面,衍生自 C 的所有類別也隱含實作介面。When a class C directly implements an interface, all classes derived from C also implement the interface implicitly. 類別宣告中指定的基底介面可以是建構的介面型別 (建構類型)。The base interfaces specified in a class declaration can be constructed interface types (Constructed types). 基底介面不能,型別參數,但它可以包含在範圍中的型別參數。A base interface cannot be a type parameter on its own, though it can involve the type parameters that are in scope. 下列程式碼說明如何實作類別和擴充建構的類型: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> {}

泛型類別宣告基底介面都必須滿足唯一性規則中所述實作的介面的唯一性The base interfaces of a generic class declaration must satisfy the uniqueness rule described in Uniqueness of implemented interfaces.

明確介面成員實作Explicit interface member implementations

為了實作介面,類別或結構可以宣告明確介面成員實作For purposes of implementing interfaces, a class or struct may declare explicit interface member implementations. 明確介面成員實作是方法、 屬性、 事件或索引子的宣告參考完整的介面成員名稱。An explicit interface member implementation is a method, property, event, or indexer declaration that references a fully qualified interface member name. 例如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) {...}
}

以下IDictionary<int,T>.thisIDictionary<int,T>.Add是明確介面成員實作。Here IDictionary<int,T>.this and IDictionary<int,T>.Add are explicit interface member implementations.

在某些情況下,可能無法適用於實作的類別,在此案例介面成員可能會使用實作明確介面成員實作介面成員的名稱。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. 類別實作檔案抽象概念,例如,可能會實作Close釋出的檔案資源的影響,而且實作的成員函式Dispose方法IDisposable介面使用明確的介面成員的實作: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);
    }
}

您不可能透過方法引動過程、 屬性存取或索引子存取中的完整限定名稱存取的明確介面成員實作。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. 明確介面成員實作只能透過介面執行個體,來存取,並在此情況下直接參考其成員名稱。An explicit interface member implementation can only be accessed through an interface instance, and is in that case referenced simply by its member name.

它是編譯時期錯誤,包括存取修飾詞,明確介面成員實作,它是編譯時期錯誤包含修飾詞abstractvirtualoverride,或staticIt 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.

明確介面成員實作各有不同的協助工具比其他成員的特性。Explicit interface member implementations have different accessibility characteristics than other members. 因為永遠不會存取其完整名稱中的方法引動過程或屬性存取透過明確介面成員實作,它們是在某種意義上私用。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. 不過,它們可以透過介面執行個體,因為它們是在某種意義上也是公用。However, since they can be accessed through an interface instance, they are in a sense also public.

明確介面成員實作有兩個主要的用途:Explicit interface member implementations serve two primary purposes:

  • 因為無法存取類別或結構的執行個體透過明確介面成員實作,它們就會允許要排除之公用介面的類別或結構的介面實作。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. 此方法特別有用的類別或結構實作不感興趣的取用者,該類別或結構的內部介面。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.
  • 明確介面成員實作可讓有相同的簽章的介面成員的去除混淆。Explicit interface member implementations allow disambiguation of interface members with the same signature. 不含明確介面成員實作它是類別或結構不可能有不同的實作的介面具有相同的簽章的成員,並傳回型別,做為它是不可能的類別或結構有任何實作在所有具有相同的簽章,但具有不同的介面成員的傳回型別。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.

有效明確介面成員實作,類別或結構必須命名為其基底類別清單中,包含的成員,其完整的名稱、 類型和參數類型完全相符的明確介面成員的介面實作。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. 因此,在下列類別Thus, in the following class

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

deklaraceIComparable.CompareTo導致編譯時期錯誤,因為IComparable基底類別清單中未列出Shape並不是基底介面的ICloneablethe 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. 同樣地,在宣告中Likewise, in the declarations

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

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

deklaraceICloneable.CloneEllipse導致編譯時期錯誤,因為ICloneable基底類別清單中未明確列出Ellipsethe 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.

介面成員的完整的名稱必須參考該成員已宣告的介面。The fully qualified name of an interface member must reference the interface in which the member was declared. 因此,在宣告中Thus, 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) {...}
}

明確介面成員實作Paint必須寫成IControl.Paintthe explicit interface member implementation of Paint must be written as IControl.Paint.

實作介面的唯一性Uniqueness of implemented interfaces

泛型型別宣告所實作的介面必須維持唯一的所有可能的建構型別。The interfaces implemented by a generic type declaration must remain unique for all possible constructed types. 而不需要這項規則,就無法判斷要呼叫的特定建構類型的正確方法。Without this rule, it would be impossible to determine the correct method to call for certain constructed types. 例如,假設允許泛型類別宣告的可寫入,如下所示: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() {...}
}

在允許這種情況,它會無法判斷哪一個程式碼執行在下列情況: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();

若要判斷泛型類型宣告的介面清單是否有效,執行下列步驟:To determine if the interface list of a generic type declaration is valid, the following steps are performed:

  • 可讓L是直接在泛型類別、 結構或介面宣告中指定的介面清單CLet L be the list of interfaces directly specified in a generic class, struct, or interface declaration C.
  • 若要新增L任何基底介面的介面已經在LAdd to L any base interfaces of the interfaces already in L.
  • 移除任何重複項目從LRemove any duplicates from L.
  • 如果任何可能會建構從建立的型別C型別引數會替代至之後會L,會導致在兩個介面L完全一樣的宣告C無效。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. 決定所有可能的建構型別時,不會考慮條件約束宣告。Constraint declarations are not considered when determining all possible constructed types.

在類別宣告X介面清單上方L組成I<U>I<V>In the class declaration X above, the interface list L consists of I<U> and I<V>. 宣告無效,因為任何建構的型別UV正在相同的型別會導致這兩個介面是相同的型別。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.

您可在整合不同的繼承層級指定的介面: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() {...}
}

此程式碼無效,即使Derived<U,V>會實作I<U>I<V>This code is valid even though Derived<U,V> implements both I<U> and I<V>. 程式碼The code

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

叫用的方法Derived,因為Derived<int,int>有效地重新實作I<int>(重新實作的介面)。invokes the method in Derived, since Derived<int,int> effectively re-implements I<int> (Interface re-implementation).

泛型方法的實作Implementation of generic methods

當泛型方法會隱含地實作介面方法,指定每個方法類型參數必須是兩個宣告中的對等 (之後任何介面類型會以適當的型別引數取代參數),其中的條件約束方法型別參數被識別序數位置,由左到右。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.

當泛型方法明確實作介面方法時,不過,不允許條件約束實作的方法。When a generic method explicitly implements an interface method, however, no constraints are allowed on the implementing method. 相反地,條件約束被繼承自介面方法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
}

此方法C.F<T>隱含地實作I<object,C,string>.F<T>The method C.F<T> implicitly implements I<object,C,string>.F<T>. 在此情況下,C.F<T>不需要 (也不會允許) 指定的條件約束T:object因為object是隱含的所有類型參數條件約束。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. 此方法C.G<T>隱含地實作I<object,C,string>.G<T>因為條件約束符合那些在介面中之後介面型別參數會取代對應的型別引數。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. 方法的條件約束C.H<T>是錯誤,因為密封類型 (string在此情況下) 無法作為條件約束。The constraint for method C.H<T> is an error because sealed types (string in this case) cannot be used as constraints. 省略此條件約束會也會是個錯誤,因為隱含的介面方法實作的條件約束,才能符合。Omitting the constraint would also be an error since constraints of implicit interface method implementations are required to match. 因此,就無法以隱含方式實作I<object,C,string>.H<T>Thus, it is impossible to implicitly implement I<object,C,string>.H<T>. 這個介面方法只可以使用明確介面成員實作來實作: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 this example, the explicit interface member implementation invokes a public method having strictly weaker constraints. 請注意,從指派ts無效,因為T繼承的條件約束T:string,即使此條件約束不是在原始程式碼中表示。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.

介面對應Interface mapping

類別或結構必須提供的介面的類別或結構的基底類別清單中列出的所有成員的實作。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. 尋找實作介面成員實作的類別或結構中的程序稱為介面對應The process of locating implementations of interface members in an implementing class or struct is known as interface mapping.

類別或結構的介面對應C找出每個成員的基底類別清單中指定每個介面的實作CInterface mapping for a class or struct C locates an implementation for each member of each interface specified in the base class list of C. 在特定介面成員的實作I.M,其中I是在其中的介面成員M宣告,會檢查每個類別或結構來判斷S開始,C和針對每個後續的基底類別的重複C,直到找到符合的: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:

  • 如果S包含相符的明確介面成員實作宣告IM,則這個成員是實作I.MIf S contains a declaration of an explicit interface member implementation that matches I and M, then this member is the implementation of I.M.
  • 否則,如果S包含的非靜態的公用成員符合宣告M,則這個成員是實作I.MOtherwise, if S contains a declaration of a non-static public member that matches M, then this member is the implementation of I.M. 如果超過一個成員的相符項目並未指定哪一個成員是實作I.MIf more than one member matches, it is unspecified which member is the implementation of I.M. 如果只可以發生這種情況S為建構的類型,其中泛型型別中宣告的兩個成員具有不同的簽章,但型別引數,使其簽章相同。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.

如果實作找不到指定的基底類別清單中的所有介面的所有成員,就會發生編譯時期錯誤CA compile-time error occurs if implementations cannot be located for all members of all interfaces specified in the base class list of C. 請注意,介面的成員會包含這些成員繼承自基底介面。Note that the members of an interface include those members that are inherited from base interfaces.

介面對應,類別成員的目的而言A符合介面成員B時:For purposes of interface mapping, a class member A matches an interface member B when:

  • AB方法,且名稱、 類型、 和型式參數清單AB完全相同。A and B are methods, and the name, type, and formal parameter lists of A and B are identical.
  • AB是屬性的名稱和型別AB互異,和A具有相同的存取子實作為B(A不允許有其他存取子,如果它不是明確的介面成員實作)。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).
  • AB是事件,及名稱和型別AB完全相同。A and B are events, and the name and type of A and B are identical.
  • AB是索引子的型別和型式參數清單AB互異,和A具有相同的存取子實作為B(A不允許有其他存取子,如果不是明確介面成員實作)。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).

值得注意的介面對應演算法的含意如下:Notable implications of the interface mapping algorithm are:

  • 明確介面成員實作優先於其他相同類別或結構中的成員時決定實作介面成員的類別或結構成員。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.
  • 或都不非公用靜態成員參與介面對應。Neither non-public nor static members participate in interface mapping.

在範例In the example

interface ICloneable
{
    object Clone();
}

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

ICloneable.Clone隸屬C變成實作CloneICloneable因為明確介面成員實作的優先順序高於其他成員。the ICloneable.Clone member of C becomes the implementation of Clone in ICloneable because explicit interface member implementations take precedence over other members.

如果類別或結構實作了兩個或多個介面,包含具有相同名稱、 類型和參數類型的成員,就可以將每個介面成員拖曳到單一類別或結構成員。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. 例如For example

interface IControl
{
    void Paint();
}

interface IForm
{
    void Paint();
}

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

在這裡,Paint這兩種IControlIForm會對應到Paint中的方法PageHere, the Paint methods of both IControl and IForm are mapped onto the Paint method in Page. 當然也很可能有兩種方法的另一個明確介面成員實作。It is of course also possible to have separate explicit interface member implementations for the two methods.

如果類別或結構實作介面,包含隱藏的成員,則某些成員必須一定實作透過明確介面成員實作。If a class or struct implements an interface that contains hidden members, then some members must necessarily be implemented through explicit interface member implementations. 例如For example

interface IBase
{
    int P { get; }
}

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

此介面的實作需要至少一個明確介面成員實作,並會採用下列格式的其中一個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() {...}
}

當類別實作多個具有相同的基底介面的介面時,可以有只有一個實作的基底介面。When a class implements multiple interfaces that have the same base interface, there can be only one implementation of the base interface. 在範例In 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) {...}
}

不可以有不同的實作,如IControl在基底類別清單中,名為IControl繼承ITextBox,而IControl繼承IListBoxit 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. 事實上,沒有這些介面的個別身分識別的概念。Indeed, there is no notion of a separate identity for these interfaces. 相反地,實作ITextBoxIListBox共用相同的實作IControl,和ComboBox只會被視為實作三個介面, IControlITextBox,和IListBoxRather, 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.

基底類別的成員會參與介面對應。The members of a base class participate in interface mapping. 在範例In the example

interface Interface1
{
    void F();
}

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

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

此方法FClass1用於Class2的實作Interface1the method F in Class1 is used in Class2's implementation of Interface1.

介面實作繼承Interface implementation inheritance

類別會繼承其基底類別所提供的所有介面實作。A class inherits all interface implementations provided by its base classes.

而不需要明確地重新實作介面衍生的類別無法以任何方式改變它繼承自其基底類別的介面對應。Without explicitly re-implementing an interface, a derived class cannot in any way alter the interface mappings it inherits from its base classes. 例如,在宣告中For example, in the declarations

interface IControl
{
    void Paint();
}

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

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

Paint方法中的TextBox隱藏Paint中的方法Control,但不會更改對應Control.Paint拖曳至IControl.Paint,和呼叫Paint透過類別執行個體和介面執行個體將有下列效果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();

不過,當介面方法對應到類別中的虛擬方法時,就可以為衍生的類別,以覆寫虛擬方法,然後修改介面的實作。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. 例如,重寫上述宣告For example, rewriting the declarations above to

interface IControl
{
    void Paint();
}

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

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

現在可觀察到下列的效果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();

明確介面成員實作不能宣告為虛擬,因為它不可以覆寫明確介面成員實作。Since explicit interface member implementations cannot be declared virtual, it is not possible to override an explicit interface member implementation. 不過,它是完全適用於呼叫另一個方法,明確介面成員實作,而且,其他方法可以宣告為虛擬化來允許衍生類別覆寫它。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. 例如For example

interface IControl
{
    void Paint();
}

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

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

在這裡,衍生自Control可以是專為實作IControl.Paint藉由覆寫PaintControl方法。Here, classes derived from Control can specialize the implementation of IControl.Paint by overriding the PaintControl method.

介面重新實作Interface re-implementation

繼承的介面實作的類別允許重新實作加在基底類別清單中的介面。A class that inherits an interface implementation is permitted to re-implement the interface by including it in the base class list.

介面重新實作能遵循完全相同介面對應的規則初始介面的實作。A re-implementation of an interface follows exactly the same interface mapping rules as an initial implementation of an interface. 因此,繼承的介面對應沒有雅致的介面對應建立重新實作介面的任何作用。Thus, the inherited interface mapping has no effect whatsoever on the interface mapping established for the re-implementation of the interface. 例如,在宣告中For example, in the declarations

interface IControl
{
    void Paint();
}

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

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

事實上,Control對應IControl.Paint拖曳至Control.IControl.Paint不會影響在重新實作MyControl,哪一個 mapIControl.Paint拖曳至MyControl.Paintthe 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.

繼承的公用成員宣告和繼承的明確介面成員宣告加入重新實作介面的介面對應程序。Inherited public member declarations and inherited explicit interface member declarations participate in the interface mapping process for re-implemented interfaces. 例如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() {}
}

這裡,實作IMethodsDerived對應至介面方法Derived.FBase.IMethods.GDerived.IMethods.H,和Base.IHere, the implementation of IMethods in Derived maps the interface methods onto Derived.F, Base.IMethods.G, Derived.IMethods.H, and Base.I.

當類別實作介面,它會隱含也會實作所有介面的基底介面。When a class implements an interface, it implicitly also implements all of that interface's base interfaces. 同樣地,重新實作也是介面的隱含的重新實作所有介面的基底介面。Likewise, a re-implementation of an interface is also implicitly a re-implementation of all of the interface's base interfaces. 例如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() {...}
}

這裡,重新實作IDerived也重新實作IBase對應IBase.F拖曳至D.FHere, the re-implementation of IDerived also re-implements IBase, mapping IBase.F onto D.F.

抽象類別和介面Abstract classes and interfaces

如同非抽象類別,抽象類別必須提供的介面的類別的基底類別清單中列出的所有成員的實作。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. 不過,抽象類別可以對應至抽象方法的介面方法。However, an abstract class is permitted to map interface methods onto abstract methods. 例如For example

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

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

這裡,實作IMethods對應FG至抽象方法,這必須覆寫在非抽象類別衍生自CHere, the implementation of IMethods maps F and G onto abstract methods, which must be overridden in non-abstract classes that derive from C.

請注意,明確介面成員實作都不能是抽象的但明確介面成員實作當然可以呼叫抽象方法。Note that explicit interface member implementations cannot be abstract, but explicit interface member implementations are of course permitted to call abstract methods. 例如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();
}

這裡,衍生自非抽象類別C才能覆寫FFGG,因此能提供的實際實作IMethodsHere, non-abstract classes that derive from C would be required to override FF and GG, thus providing the actual implementation of IMethods.