Skip to content

Example metadata: interfaces.md #709

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 11, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 45 additions & 40 deletions standard/interfaces.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ If the variance annotation is `out`, the type parameter is said to be ***covaria

> *Example*: In the following:
>
> <!-- Example: {template:"standalone-lib", name:"VariantTypeParameterLists"} -->
> <!-- Example: {template:"standalone-lib-without-using", name:"VariantTypeParameterLists"} -->
> ```csharp
> interface C<out X, in Y, Z>
> {
Expand Down Expand Up @@ -153,7 +153,7 @@ The ***base interfaces*** of an interface are the explicit base interfaces and t

> *Example*: In the following code
>
> <!-- Example: {template:"standalone-lib", name:"BaseInterfaces1"} -->
> <!-- Example: {template:"standalone-lib-without-using", name:"BaseInterfaces1"} -->
> ```csharp
> interface IControl
> {
Expand Down Expand Up @@ -181,7 +181,7 @@ Members inherited from a constructed generic type are inherited after type subst

> *Example*: In the following code
>
> <!-- Example: {template:"standalone-lib", name:"BaseInterfaces2"} -->
> <!-- Example: {template:"standalone-lib-without-using", name:"BaseInterfaces2"} -->
> ```csharp
> interface IBase<T>
> {
Expand All @@ -194,7 +194,7 @@ Members inherited from a constructed generic type are inherited after type subst
> }
> ```
>
> the interface IDerived inherits the Combine method after the type parameter `T` is replaced with `string[,]`.
> the interface `IDerived` inherits the `Combine` method after the type parameter `T` is replaced with `string[,]`.
>
> *end example*

Expand Down Expand Up @@ -273,7 +273,7 @@ These rules ensure that any covariant or contravariant usage of the interface re

> *Example*:
>
> <!-- Example: {template:"standalone-lib", name:"InterfaceMethods1", expectedErrors:["CS1961"]} -->
> <!-- Example: {template:"standalone-lib-without-using", name:"InterfaceMethods1", expectedErrors:["CS1961"]} -->
> ```csharp
> interface I<out T>
> {
Expand All @@ -285,7 +285,8 @@ These rules ensure that any covariant or contravariant usage of the interface re
>
> Were this restriction not in place it would be possible to violate type safety in the following manner:
>
> <!-- IncompleteExample: {template:"standalone-lib", name:"InterfaceMethods2", replaceEllipsis:true, expectedErrors:["x","x"], expectedWarnings:["x","x"]} -->
> <!-- Incomplete$Example: {template:"standalone-lib-without-using", name:"InterfaceMethods2", replaceEllipsis:true, expectedErrors:["x","x"], expectedWarnings:["x","x"]} -->
> <!-- FIX: need to define I<T>, then perhaps break into 2 files, first one a standalone-lib, the second, code-in-class-lib. -->
> ```csharp
> class B {}
> class D : B {}
Expand Down Expand Up @@ -373,7 +374,7 @@ For interfaces that are strictly single-inheritance (each interface in the inher

> *Example*: In the following code
>
> <!-- NeedsReviewExample: {template:"standalone-lib", name:"InterfaceMemberAccess1", expectedErrors:["x","x"], expectedWarnings:["x","x"]} -->
> <!-- NeedsReview$Example: {template:"standalone-lib-without-using", name:"InterfaceMemberAccess1", expectedErrors:["x","x"], expectedWarnings:["x","x"]} -->
> ```csharp
> interface IList
> {
Expand Down Expand Up @@ -407,7 +408,7 @@ For interfaces that are strictly single-inheritance (each interface in the inher
<!-- markdownlint-enable MD028 -->
> *Example*: In the following code
>
> <!-- Example: {template:"standalone-lib", name:"InterfaceMemberAccess2"} -->
> <!-- Example: {template:"standalone-lib-without-using", name:"InterfaceMemberAccess2"} -->
> ```csharp
> interface IInteger
> {
Expand Down Expand Up @@ -441,7 +442,7 @@ For interfaces that are strictly single-inheritance (each interface in the inher
<!-- markdownlint-enable MD028 -->
> *Example*: In the following code
>
> <!-- Example: {template:"standalone-lib", name:"InterfaceMemberAccess3"} -->
> <!-- Example: {template:"standalone-lib-without-using", name:"InterfaceMemberAccess3"} -->
> ```csharp
> interface IBase
> {
Expand Down Expand Up @@ -484,7 +485,7 @@ An interface member is sometimes referred to by its ***qualified interface membe

> *Example*: Given the declarations
>
> <!-- Example: {template:"standalone-lib", name:"QualifiedInterfaceMemberNames1"} -->
> <!-- Example: {template:"standalone-lib-without-using", name:"QualifiedInterfaceMemberNames1"} -->
> ```csharp
> interface IControl
> {
Expand All @@ -505,7 +506,7 @@ When an interface is part of a namespace, a qualified interface member name can

> *Example*:
>
> <!-- Example: {template:"standalone-lib", name:"QualifiedInterfaceMemberNames2"} -->
> <!-- Example: {template:"standalone-lib-without-using", name:"QualifiedInterfaceMemberNames2"} -->
> ```csharp
> namespace System
> {
Expand All @@ -528,7 +529,7 @@ Interfaces may be implemented by classes and structs. To indicate that a class o

> *Example*:
>
> <!-- IncompleteExample: {template:"standalone-lib", name:"InterfaceImplementations1", replaceEllipsis:true, expectedErrors:["x","x"], expectedWarnings:["x","x"]} -->
> <!-- Example: {template:"standalone-lib-without-using", name:"InterfaceImplementations1", replaceEllipsis:true, customEllipsisReplacements: ["return default;", "return default;"]} -->
> ```csharp
> interface ICloneable
> {
Expand All @@ -553,7 +554,7 @@ A class or struct that directly implements an interface also implicitly implemen

> *Example*:
>
> <!-- Example: {template:"standalone-lib", name:"InterfaceImplementations2", replaceEllipsis:true} -->
> <!-- Example: {template:"standalone-lib-without-using", name:"InterfaceImplementations2", replaceEllipsis:true} -->
> ```csharp
> interface IControl
> {
Expand Down Expand Up @@ -582,7 +583,7 @@ The base interfaces specified in a class declaration can be constructed interfac

> *Example*: The following code illustrates how a class can implement constructed interface types:
>
> <!-- Example: {template:"standalone-lib", name:"InterfaceImplementations3"} -->
> <!-- Example: {template:"standalone-lib-without-using", name:"InterfaceImplementations3"} -->
> ```csharp
> class C<U, V> {}
> interface I1<V> {}
Expand All @@ -600,7 +601,7 @@ For purposes of implementing interfaces, a class or struct may declare ***explic

> *Example*:
>
> <!-- IncompleteExample: {template:"standalone-lib", name:"ExplicitInterfaceMemberImplementations1", replaceEllipsis:true, expectedErrors:["CS0161","CS0161"]} -->
> <!-- Example: {template:"standalone-lib-without-using", name:"ExplicitInterfaceMemberImplementations1", replaceEllipsis:true, customEllipsisReplacements: ["return default;", "get { return default; }", "return;"]} -->
> ```csharp
> interface IList<T>
> {
Expand Down Expand Up @@ -629,7 +630,7 @@ For purposes of implementing interfaces, a class or struct may declare ***explic
<!-- markdownlint-enable MD028 -->
> *Example*: In some cases, the name of an interface member might not be appropriate for the implementing class, in which case, the interface member may be implemented using explicit interface member implementation. 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:
>
> <!-- Example: {template:"standalone-lib", name:"ExplicitInterfaceMemberImplementations2"} -->
> <!-- Example: {template:"standalone-lib-without-using", name:"ExplicitInterfaceMemberImplementations2"} -->
> ```csharp
> interface IDisposable
> {
Expand Down Expand Up @@ -668,7 +669,7 @@ For an explicit interface member implementation to be valid, the class or struct

> *Example*: Thus, in the following class
>
> <!-- IncompleteExample: {template:"standalone-lib", name:"ExplicitInterfaceMemberImplementations3", replaceEllipsis:true, expectedErrors:["CS0540"]} -->
> <!-- Example: {template:"standalone-lib", name:"ExplicitInterfaceMemberImplementations3", replaceEllipsis:true, customEllipsisReplacements: ["return default;", "return default;"], expectedErrors:["CS0540"]} -->
> ```csharp
> class Shape : ICloneable
> {
Expand All @@ -679,7 +680,7 @@ For an explicit interface member implementation to be valid, the class or struct
>
> 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`. Likewise, in the declarations
>
> <!-- IncompleteExample: {template:"standalone-lib", name:"ExplicitInterfaceMemberImplementations4", replaceEllipsis:true, expectedErrors:["CS0540"]} -->
> <!-- Example: {template:"standalone-lib", name:"ExplicitInterfaceMemberImplementations4", replaceEllipsis:true, customEllipsisReplacements: ["return default;", "return default;"], expectedErrors:["CS0540"]} -->
> ```csharp
> class Shape : ICloneable
> {
Expand All @@ -700,7 +701,7 @@ The qualified interface member name of an explicit interface member implementati

> *Example*: Thus, in the declarations
>
> <!-- Example: {template:"standalone-lib", name:"ExplicitInterfaceMemberImplementations5", replaceEllipsis:true} -->
> <!-- Example: {template:"standalone-lib-without-using", name:"ExplicitInterfaceMemberImplementations5", replaceEllipsis:true} -->
> ```csharp
> interface IControl
> {
Expand Down Expand Up @@ -729,7 +730,7 @@ The interfaces implemented by a generic type declaration shall remain unique for

> *Example*: Suppose a generic class declaration were permitted to be written as follows:
>
> <!-- Example: {template:"standalone-lib", name:"UniquenessOfImplementedInterfaces1", replaceEllipsis:true, expectedErrors:["CS0695"]} -->
> <!-- Example: {template:"standalone-lib-without-using", name:"UniquenessOfImplementedInterfaces1", replaceEllipsis:true, expectedErrors:["CS0695"]} -->
> ```csharp
> interface I<T>
> {
Expand Down Expand Up @@ -763,7 +764,7 @@ To determine if the interface list of a generic type declaration is valid, the f

It is possible for interfaces specified at different inheritance levels to unify:

<!-- Example: {template:"standalone-lib", name:"UniquenessOfImplementedInterfaces2", replaceEllipsis:true} -->
<!-- Example: {template:"standalone-lib-without-using", name:"UniquenessOfImplementedInterfaces2", replaceEllipsis:true} -->
```csharp
interface I<T>
{
Expand Down Expand Up @@ -796,7 +797,8 @@ When a generic method implicitly implements an interface method, the constraints

> *Example*: In the following code:
>
> <!-- Example: {template:"standalone-lib", name:"ImplementationOfGenericMethods1", replaceEllipsis:true, expectedErrors:["CS0425","CS0701"]} -->
> <!-- Example: {template:"standalone-lib-without-using", name:"ImplementationOfGenericMethods1", replaceEllipsis:true, expectedErrors:["CS0425","CS0701"]} -->
> <!-- Maintenance Note: A version of this type exists in additional-files as "ITTT.cs". As such, certain changes to this type definition might need to be reflected in that file, in which case, *all* examples using that file should be tested. -->
> ```csharp
> interface I<X, Y, Z>
> {
Expand All @@ -815,7 +817,7 @@ When a generic method implicitly implements an interface method, the constraints
>
> the method `C.F<T>` implicitly implements `I<object,C,string>.F<T>`. 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. 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. 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. 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:
>
> <!-- IncompleteExample: {template:"standalone-lib", name:"ImplementationOfGenericMethods2", replaceEllipsis:true, expectedErrors:["x","x"], expectedWarnings:["x","x"]} -->
> <!-- Example: {template:"standalone-lib-without-using", name:"ImplementationOfGenericMethods2", replaceEllipsis:true, additionalFiles:["ITTT.cs"]} -->
> ```csharp
> class C : I<object, C, string>
> {
Expand Down Expand Up @@ -852,7 +854,7 @@ Members of a constructed interface type are considered to have any type paramete

> *Example*: For example, given the generic interface declaration:
>
> <!-- Example: {template:"standalone-lib", name:"InterfaceMapping1"} -->
> <!-- Example: {template:"standalone-lib-without-using", name:"InterfaceMapping1"} -->
> ```csharp
> interface I<T>
> {
Expand Down Expand Up @@ -884,7 +886,7 @@ Notable implications of the interface-mapping algorithm are:

> *Example*: In the following code
>
> <!-- IncompleteExample: {template:"standalone-lib", name:"InterfaceMapping3", replaceEllipsis:true, expectedErrors:["x","x"], expectedWarnings:["x","x"]} -->
> <!-- Example: {template:"standalone-lib-without-using", name:"InterfaceMapping3", replaceEllipsis:true, customEllipsisReplacements: ["return default;", "return default;"]} -->
> ```csharp
> interface ICloneable
> {
Expand All @@ -906,7 +908,7 @@ If a class or struct implements two or more interfaces containing a member with

> *Example*:
>
> <!-- Example: {template:"standalone-lib", name:"InterfaceMapping4", replaceEllipsis:true} -->
> <!-- Example: {template:"standalone-lib-without-using", name:"InterfaceMapping4", replaceEllipsis:true} -->
> ```csharp
> interface IControl
> {
Expand All @@ -932,7 +934,7 @@ If a class or struct implements an interface that contains hidden members, then

> *Example*:
>
> <!-- Example: {template:"standalone-lib", name:"InterfaceMapping5"} -->
> <!-- Example: {template:"standalone-lib-without-using", name:"InterfaceMapping5"} -->
> ```csharp
> interface IBase
> {
Expand All @@ -947,7 +949,8 @@ If a class or struct implements an interface that contains hidden members, then
>
> An implementation of this interface would require at least one explicit interface member implementation, and would take one of the following forms
>
> <!-- IncompleteExample: {template:"standalone-lib", name:"InterfaceMapping6", replaceEllipsis:true, expectedErrors:["x","x"], expectedWarnings:["x","x"]} -->
> <!-- Example: {template:"standalone-lib-without-using", name:"InterfaceMapping6", replaceEllipsis:true, customEllipsisReplacements: ["return default;", "return default;", "return default;"], additionalFiles:["IBase.cs", "IDerived.cs"]} -->
> <!-- Maintenance Note: A version of this type exists in additional-files as "IBase.cs" and "IDerived.cs". As such, certain changes to this type definition might need to be reflected in that file, in which case, *all* examples using that file should be tested. -->
> ```csharp
> class C1 : IDerived
> {
Expand All @@ -972,7 +975,7 @@ When a class implements multiple interfaces that have the same base interface, t

> *Example*: In the following code
>
> <!-- Example: {template:"standalone-lib", name:"InterfaceMapping7", replaceEllipsis:true} -->
> <!-- Example: {template:"standalone-lib-without-using", name:"InterfaceMapping7", replaceEllipsis:true} -->
> ```csharp
> interface IControl
> {
Expand Down Expand Up @@ -1005,7 +1008,7 @@ The members of a base class participate in interface mapping.

> *Example*: In the following code
>
> <!-- Example: {template:"standalone-lib", name:"InterfaceMapping8"} -->
> <!-- Example: {template:"standalone-lib-without-using", name:"InterfaceMapping8"} -->
> ```csharp
> interface Interface1
> {
Expand Down Expand Up @@ -1036,7 +1039,8 @@ Without explicitly re-implementing an interface, a derived class cannot in any w

> *Example*: In the declarations
>
> <!-- Example: {template:"standalone-lib", name:"InterfaceImplementationInheritance1", replaceEllipsis:true} -->
> <!-- Example: {template:"standalone-lib-without-using", name:"InterfaceImplementationInheritance1", replaceEllipsis:true} -->
> <!-- Maintenance Note: A version of these types exists in additional-files as "IControlControlTextBox1.cs". As such, certain changes to these type definitions might need to be reflected in that file, in which case, *all* examples using that file should be tested. -->
> ```csharp
> interface IControl
> {
Expand All @@ -1056,7 +1060,7 @@ Without explicitly re-implementing an interface, a derived class cannot in any w
>
> 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
>
> <!-- IncompleteExample: {template:"standalone-lib", name:"InterfaceImplementationInheritance2", expectedErrors:["x","x"], expectedWarnings:["x","x"]} -->
> <!-- Example: {template:"standalone-console-without-using", name:"InterfaceImplementationInheritance2", additionalFiles:["IControlControlTextBox1.cs"]} -->
> ```csharp
> Control c = new Control();
> TextBox t = new TextBox();
Expand All @@ -1074,7 +1078,8 @@ However, when an interface method is mapped onto a virtual method in a class, it

> *Example*: Rewriting the declarations above to
>
> <!-- Example: {template:"standalone-lib", name:"InterfaceImplementationInheritance3", replaceEllipsis:true} -->
> <!-- Example: {template:"standalone-lib-without-using", name:"InterfaceImplementationInheritance3", replaceEllipsis:true} -->
> <!-- Maintenance Note: A version of these types exists in additional-files as "IControlControlTextBox2.cs". As such, certain changes to these type definitions might need to be reflected in that file, in which case, *all* examples using that file should be tested. -->
> ```csharp
> interface IControl
> {
Expand All @@ -1094,7 +1099,7 @@ However, when an interface method is mapped onto a virtual method in a class, it
>
> the following effects will now be observed
>
> <!-- IncompleteExample: {template:"standalone-lib", name:"InterfaceImplementationInheritance4", expectedErrors:["x","x"], expectedWarnings:["x","x"]} -->
> <!-- Example: {template:"standalone-console-without-using", name:"InterfaceImplementationInheritance4", additionalFiles:["IControlControlTextBox2.cs"]} -->
> ```csharp
> Control c = new Control();
> TextBox t = new TextBox();
Expand All @@ -1112,7 +1117,7 @@ Since explicit interface member implementations cannot be declared virtual, it i

> *Example*:
>
> <!-- Example: {template:"standalone-lib", name:"InterfaceImplementationInheritance5", replaceEllipsis:true} -->
> <!-- Example: {template:"standalone-lib-without-using", name:"InterfaceImplementationInheritance5", replaceEllipsis:true} -->
> ```csharp
> interface IControl
> {
Expand Down Expand Up @@ -1143,7 +1148,7 @@ A re-implementation of an interface follows exactly the same interface mapping r

> *Example*: In the declarations
>
> <!-- Example: {template:"standalone-lib", name:"InterfaceRe-implementation1", replaceEllipsis:true} -->
> <!-- Example: {template:"standalone-lib-without-using", name:"InterfaceRe-implementation1", replaceEllipsis:true} -->
> ```csharp
> interface IControl
> {
Expand All @@ -1169,7 +1174,7 @@ Inherited public member declarations and inherited explicit interface member dec

> *Example*:
>
> <!-- Example: {template:"standalone-lib", name:"InterfaceRe-implementation2"} -->
> <!-- Example: {template:"standalone-lib-without-using", name:"InterfaceRe-implementation2"} -->
> ```csharp
> interface IMethods
> {
Expand Down Expand Up @@ -1202,7 +1207,7 @@ When a class implements an interface, it implicitly also implements all that int

> *Example*:
>
> <!-- Example: {template:"standalone-lib", name:"InterfaceRe-implementation3", replaceEllipsis:true} -->
> <!-- Example: {template:"standalone-lib-without-using", name:"InterfaceRe-implementation3", replaceEllipsis:true} -->
> ```csharp
> interface IBase
> {
Expand Down Expand Up @@ -1237,7 +1242,7 @@ Like a non-abstract class, an abstract class shall provide implementations of al

> *Example*:
>
> <!-- Example: {template:"standalone-lib", name:"AbstractClassesAndInterfaces1"} -->
> <!-- Example: {template:"standalone-lib-without-using", name:"AbstractClassesAndInterfaces1"} -->
> ```csharp
> interface IMethods
> {
Expand All @@ -1260,7 +1265,7 @@ Explicit interface member implementations cannot be abstract, but explicit inter

> *Example*:
>
> <!-- Example: {template:"standalone-lib", name:"AbstractClassesAndInterfaces2"} -->
> <!-- Example: {template:"standalone-lib-without-using", name:"AbstractClassesAndInterfaces2"} -->
> ```csharp
> interface IMethods
> {
Expand Down