diff --git a/docs/csharp/language-reference/attributes/general.md b/docs/csharp/language-reference/attributes/general.md index a11735111e3b7..c3ea4dace702b 100644 --- a/docs/csharp/language-reference/attributes/general.md +++ b/docs/csharp/language-reference/attributes/general.md @@ -1,6 +1,6 @@ --- title: "Attributes interpreted by the compiler: Miscellaneous" -ms.date: 10/26/2023 +ms.date: 07/26/2024 description: "Learn about attributes that affect code generated by the compiler: the Conditional, Obsolete, AttributeUsage, ModuleInitializer, and SkipLocalsInit attributes." --- # Miscellaneous attributes interpreted by the C# compiler @@ -128,7 +128,7 @@ You add the interface. -The constructor to the `AsyncMethodBuilder` attribute specifies the type of the associated builder. The builder must implement the following accessible members: +The constructor to the `AsyncMethodBuilder` attribute specifies the type of the associated builder. The builder must implement the following accessible members: * A static `Create()` method that returns the type of the builder. * A readable `Task` property that returns the async return type. diff --git a/docs/csharp/language-reference/attributes/global.md b/docs/csharp/language-reference/attributes/global.md index c8032fdaf2058..cfd64d0afa665 100644 --- a/docs/csharp/language-reference/attributes/global.md +++ b/docs/csharp/language-reference/attributes/global.md @@ -1,6 +1,6 @@ --- title: "Attributes interpreted by the compiler: Global attributes" -ms.date: 12/16/2020 +ms.date: 07/26/2024 description: Attributes provide metadata the compiler uses to understand more semantics of your program --- # Assembly level attributes interpreted by the C# compiler @@ -29,11 +29,11 @@ The following table shows the identity attributes. |---------------|-------------| ||Specifies the version of an assembly.| ||Specifies which culture the assembly supports.| -||Specifies whether an assembly supports side-by-side execution on the same computer, in the same process, or in the same application domain.| +||Specifies a bitwise combination of flags for an assembly, describing just-in-time (JIT) compiler options, whether the assembly is retargetable, and whether it has a full or tokenized public key. | ## Informational attributes -You use informational attributes to provide additional company or product information for an assembly. The following table shows the informational attributes defined in the namespace. +You use informational attributes to provide more company or product information for an assembly. The following table shows the informational attributes defined in the namespace. |Attribute|Purpose| |---------------|-------------| diff --git a/docs/csharp/language-reference/builtin-types/ref-struct.md b/docs/csharp/language-reference/builtin-types/ref-struct.md index d8cc0061300a8..07b18341646b9 100644 --- a/docs/csharp/language-reference/builtin-types/ref-struct.md +++ b/docs/csharp/language-reference/builtin-types/ref-struct.md @@ -1,7 +1,7 @@ --- title: "ref struct types" description: Learn about the ref struct type in C# -ms.date: 06/28/2024 +ms.date: 07/26/2024 --- # `ref` structure types (C# reference) @@ -60,16 +60,16 @@ The `Span` type stores a reference through which it accesses the contiguous e You can define a disposable `ref struct`. To do that, ensure that a `ref struct` fits the [disposable pattern](~/_csharplang/proposals/csharp-8.0/using.md#pattern-based-using). That is, it has an instance `Dispose` method, which is accessible, parameterless and has a `void` return type. You can use the [using statement or declaration](../statements/using.md) with an instance of a disposable `ref struct`. -Beginning with C# 13, you can also implement the on `ref struct` types. However, overload resolution prefers the disposable pattern to the interface method. Only if a suitable `Dispose` method isn't found will an `IDisposable.Dispose` method be chosen. +Beginning with C# 13, you can also implement the on `ref struct` types. However, overload resolution prefers the disposable pattern to the interface method. The compiler resolves to an `IDisposable.Dispose` method only whan a suitable `Dispose` method isn't found. ## Restrictions for `ref struct` types that implement an interface These restrictions ensure that a `ref struct` type that implements an interface obeys the necessary [ref safety](~/_csharpstandard/standard/structs.md#1623-ref-modifier) rules. -- A `ref struct` can't be converted to an instance of an interface it implements. This includes the implicit conversion when you use a `ref struct` type as an argument when the parameter is an interface type. The conversion results in a boxing conversion, which violates ref safety. +- A `ref struct` can't be converted to an instance of an interface it implements. This restriction includes the implicit conversion when you use a `ref struct` type as an argument when the parameter is an interface type. The conversion results in a boxing conversion, which violates ref safety. - A `ref struct` that implements an interface *must* implement all interface members. The `ref struct` must implement members where the interface includes a default implementation. -The compiler enforces these restrictions. If you write `ref struct` types that implement interfaces, each new update may include new [default interface members](../keywords/interface.md#default-interface-members). Until you provide an implementation for these new methods, your application won't compile. +The compiler enforces these restrictions. If you write `ref struct` types that implement interfaces, each new update might include new [default interface members](../keywords/interface.md#default-interface-members). Until you provide an implementation for these new methods, your application won't compile. > [!IMPORTANT] > A `ref struct` that implements an interface includes the potential for later source-breaking and binary-breaking changes. The break occurs if a `ref struct` implements an interface defined in another assembly, and that assembly provides an update which adds default members to that interface. diff --git a/docs/csharp/language-reference/keywords/interface.md b/docs/csharp/language-reference/keywords/interface.md index 7ffdd172c6579..82aa89f6a223c 100644 --- a/docs/csharp/language-reference/keywords/interface.md +++ b/docs/csharp/language-reference/keywords/interface.md @@ -1,7 +1,7 @@ --- description: "Use the `interface` keyword to define contracts that any implementing type must support. Interfaces provide the means to create common behavior among a set of unrelated types." title: "interface keyword" -ms.date: 07/08/2022 +ms.date: 07/26/2024 f1_keywords: - "interface_CSharpKeyword" helpviewer_keywords: @@ -15,6 +15,10 @@ In the following example, class `ImplementationClass` must implement a method na For more information and examples, see [Interfaces](../../fundamentals/types/interfaces.md). +A top-level interface, one declared in a namespace but not nested inside another type, can be declared `public` or `internal`. The default is `internal`. Nested interface declarations, those nested inside another type, can be declared using any access modifier. + +Interface members without an implementation can't include an access modifier. Members with a default implementation can include any access modifier. + ## Example interface [!code-csharp[csrefKeywordsTypes#14](~/samples/snippets/csharp/VS_Snippets_VBCSharp/csrefKeywordsTypes/CS/keywordsTypes.cs#14)] @@ -63,7 +67,11 @@ public interface INamed } ``` -An interface can inherit from one or more base interfaces. When an interface [overrides a method](override.md) implemented in a base interface, it must use the [explicit interface implementation](../../programming-guide/interfaces/explicit-interface-implementation.md) syntax. +An interface can inherit from one or more base interfaces. When an interface inherits from another interface, a type implementing the derived interface must implement all the members in the base interfaces as well as those declared in the derived interface, as shown in the following code: + +:::code language="csharp" source="./snippets/DefineTypes.cs" id="SnippetDerivedInterfaces"::: + +When an interface [overrides a method](override.md) implemented in a base interface, it must use the [explicit interface implementation](../../programming-guide/interfaces/explicit-interface-implementation.md) syntax. When a base type list contains a base class and interfaces, the base class must come first in the list. diff --git a/docs/csharp/language-reference/keywords/snippets/DefineTypes.cs b/docs/csharp/language-reference/keywords/snippets/DefineTypes.cs index e10518b60605d..7f8a5275c3c12 100644 --- a/docs/csharp/language-reference/keywords/snippets/DefineTypes.cs +++ b/docs/csharp/language-reference/keywords/snippets/DefineTypes.cs @@ -47,3 +47,23 @@ static void Main() } // Output: My Point: x=2, y=3 // + +// +public interface I1 +{ + void M1(); +} + +public interface I2 : I1 +{ + void M2; +} + +public class C : I2 +{ + // implements I1.M1 + public void M1() { } + // implements I2.M2 + public void M2() { } +} +// \ No newline at end of file diff --git a/docs/csharp/language-reference/keywords/where-generic-type-constraint.md b/docs/csharp/language-reference/keywords/where-generic-type-constraint.md index 3ae395507f055..279d63724867d 100644 --- a/docs/csharp/language-reference/keywords/where-generic-type-constraint.md +++ b/docs/csharp/language-reference/keywords/where-generic-type-constraint.md @@ -2,7 +2,7 @@ description: "where (generic type constraint) - C# Reference" title: "where (generic type constraint)" -ms.date: 04/28/2021 +ms.date: 07/26/2024 f1_keywords: - "whereconstraint" - "whereconstraint_CSharpKeyword" @@ -28,17 +28,17 @@ The `where` clause can also include a base class constraint. The base class cons :::code language="csharp" source="snippets/GenericWhereConstraints.cs" ID="Snippet2"::: -In a nullable context, the nullability of the base class type is enforced. If the base class is non-nullable (for example `Base`), the type argument must be non-nullable. If the base class is nullable (for example `Base?`), the type argument may be either a nullable or non-nullable reference type. The compiler issues a warning if the type argument is a nullable reference type when the base class is non-nullable. +In a nullable context, the nullability of the base class type is enforced. If the base class is non-nullable (for example `Base`), the type argument must be non-nullable. If the base class is nullable (for example `Base?`), the type argument can be either a nullable or non-nullable reference type. The compiler issues a warning if the type argument is a nullable reference type when the base class is non-nullable. -The `where` clause can specify that the type is a `class` or a `struct`. The `struct` constraint removes the need to specify a base class constraint of `System.ValueType`. The `System.ValueType` type may not be used as a base class constraint. The following example shows both the `class` and `struct` constraints: +The `where` clause can specify that the type is a `class` or a `struct`. The `struct` constraint removes the need to specify a base class constraint of `System.ValueType`. The `System.ValueType` type can't be used as a base class constraint. The following example shows both the `class` and `struct` constraints: :::code language="csharp" source="snippets/GenericWhereConstraints.cs" ID="Snippet3"::: In a nullable context, the `class` constraint requires a type to be a non-nullable reference type. To allow nullable reference types, use the `class?` constraint, which allows both nullable and non-nullable reference types. -The `where` clause may include the `notnull` constraint. The `notnull` constraint limits the type parameter to non-nullable types. The type may be a [value type](../builtin-types/value-types.md) or a non-nullable reference type. The `notnull` constraint is available for code compiled in a [`nullable enable` context](../../nullable-references.md#nullable-contexts). Unlike other constraints, if a type argument violates the `notnull` constraint, the compiler generates a warning instead of an error. Warnings are only generated in a `nullable enable` context. +The `where` clause can include the `notnull` constraint. The `notnull` constraint limits the type parameter to non-nullable types. The type can be a [value type](../builtin-types/value-types.md) or a non-nullable reference type. The `notnull` constraint is available for code compiled in a [`nullable enable` context](../../nullable-references.md#nullable-contexts). Unlike other constraints, if a type argument violates the `notnull` constraint, the compiler generates a warning instead of an error. Warnings are only generated in a `nullable enable` context. -The addition of nullable reference types introduces a potential ambiguity in the meaning of `T?` in generic methods. If `T` is a `struct`, `T?` is the same as . However, if `T` is a reference type, `T?` means that `null` is a valid value. The ambiguity arises because overriding methods can't include constraints. The new `default` constraint resolves this ambiguity. You'll add it when a base class or interface declares two overloads of a method, one that specifies the `struct` constraint, and one that doesn't have either the `struct` or `class` constraint applied: +The addition of nullable reference types introduces a potential ambiguity in the meaning of `T?` in generic methods. If `T` is a `struct`, `T?` is the same as . However, if `T` is a reference type, `T?` means that `null` is a valid value. The ambiguity arises because overriding methods can't include constraints. The new `default` constraint resolves this ambiguity. You add it when a base class or interface declares two overloads of a method, one that specifies the `struct` constraint, and one that doesn't have either the `struct` or `class` constraint applied: :::code language="csharp" source="snippets/GenericWhereConstraints.cs" ID="BaseClass"::: @@ -51,15 +51,15 @@ You use the `default` constraint to specify that your derived class overrides th :::code language="csharp" source="snippets/GenericWhereConstraints.cs" ID="NotNull"::: -The `where` clause may also include an `unmanaged` constraint. The `unmanaged` constraint limits the type parameter to types known as [unmanaged types](../builtin-types/unmanaged-types.md). The `unmanaged` constraint makes it easier to write low-level interop code in C#. This constraint enables reusable routines across all unmanaged types. The `unmanaged` constraint can't be combined with the `class` or `struct` constraint. The `unmanaged` constraint enforces that the type must be a `struct`: +The `where` clause can also include an `unmanaged` constraint. The `unmanaged` constraint limits the type parameter to types known as [unmanaged types](../builtin-types/unmanaged-types.md). The `unmanaged` constraint makes it easier to write low-level interop code in C#. This constraint enables reusable routines across all unmanaged types. The `unmanaged` constraint can't be combined with the `class` or `struct` constraint. The `unmanaged` constraint enforces that the type must be a `struct`: :::code language="csharp" source="snippets/GenericWhereConstraints.cs" ID="Snippet4"::: -The `where` clause may also include a constructor constraint, `new()`. That constraint makes it possible to create an instance of a type parameter using the `new` operator. The [new() Constraint](new-constraint.md) lets the compiler know that any type argument supplied must have an accessible parameterless constructor. For example: +The `where` clause can also include a constructor constraint, `new()`. That constraint makes it possible to create an instance of a type parameter using the `new` operator. The [new() Constraint](new-constraint.md) lets the compiler know that any type argument supplied must have an accessible parameterless constructor. For example: :::code language="csharp" source="snippets/GenericWhereConstraints.cs" ID="Snippet5"::: -The `new()` constraint appears last in the `where` clause, unless it is followed by the `allows ref struct` anti-constraint. The `new()` constraint can't be combined with the `struct` or `unmanaged` constraints. All types satisfying those constraints must have an accessible parameterless constructor, making the `new()` constraint redundant. +The `new()` constraint appears last in the `where` clause, unless it's followed by the `allows ref struct` anti-constraint. The `new()` constraint can't be combined with the `struct` or `unmanaged` constraints. All types satisfying those constraints must have an accessible parameterless constructor, making the `new()` constraint redundant. This anti-constraint declares that the type argument for `T` can be a `ref struct` type. For example: diff --git a/docs/csharp/programming-guide/generics/constraints-on-type-parameters.md b/docs/csharp/programming-guide/generics/constraints-on-type-parameters.md index 3b8ee5f48c8db..5a826ffdfb7a8 100644 --- a/docs/csharp/programming-guide/generics/constraints-on-type-parameters.md +++ b/docs/csharp/programming-guide/generics/constraints-on-type-parameters.md @@ -1,7 +1,7 @@ --- title: "Constraints on type parameters" description: Learn about constraints on type parameters. Constraints tell the compiler what capabilities a type argument must have. -ms.date: 03/11/2024 +ms.date: 07/26/2024 f1_keywords: - "defaultconstraint_CSharpKeyword" - "notnull_CSharpKeyword" @@ -35,7 +35,7 @@ Constraints inform the compiler about the capabilities a type argument must have Some constraints are mutually exclusive, and some constraints must be in a specified order: - You can apply at most one of the `struct`, `class`, `class?`, `notnull`, and `unmanaged` constraints. If you supply any of these constraints, it must be the first constraint specified for that type parameter. -- The base class constraint, (`where T : Base` or `where T : Base?`), can't be combined with any of the constraints `struct`, `class`, `class?`, `notnull`, or `unmanaged`. +- The base class constraint (`where T : Base` or `where T : Base?`) can't be combined with any of the constraints `struct`, `class`, `class?`, `notnull`, or `unmanaged`. - You can apply at most one base class constraint, in either form. If you want to support the nullable base type, use `Base?`. - You can't name both the non-nullable and nullable form of an interface as a constraint. - The `new()` constraint can't be combined with the `struct` or `unmanaged` constraint. If you specify the `new()` constraint, it must be the last constraint for that type parameter. Anti-constraints, if applicable, can follow the `new()` constraint. @@ -121,11 +121,11 @@ You can use or - class EmployeeList where T : Employee, System.Collections.Generic.IList, IDisposable, new() + class EmployeeList where T : notnull, Employee, IComparable, new() { // ... + public void AddDefault() + { + T t = new T(); + // ... + } } //