diff --git a/docs/csharp/language-reference/builtin-types/unmanaged-types.md b/docs/csharp/language-reference/builtin-types/unmanaged-types.md index 0a8c2585c8fb0..c1bab9748d3a3 100644 --- a/docs/csharp/language-reference/builtin-types/unmanaged-types.md +++ b/docs/csharp/language-reference/builtin-types/unmanaged-types.md @@ -1,20 +1,28 @@ --- title: "Unmanaged types - C# reference" -ms.date: 07/23/2019 +ms.date: 09/06/2019 helpviewer_keywords: - "unmanaged type [C#]" --- # Unmanaged types (C# reference) -An **unmanaged type** is any type that isn't a reference type or constructed type (a type that includes at least one type argument), and doesn't contain reference type or constructed type fields at any level of nesting. In other words, an unmanaged type is one of the following: +A type is an **unmanaged type** if it's any of the following types: - `sbyte`, `byte`, `short`, `ushort`, `int`, `uint`, `long`, `ulong`, `char`, `float`, `double`, `decimal`, or `bool` - Any [enum](../keywords/enum.md) type - Any [pointer](../../programming-guide/unsafe-code-pointers/pointer-types.md) type -- Any user-defined [struct](../keywords/struct.md) type that is not a constructed type and contains fields of unmanaged types only +- Any user-defined [struct](../keywords/struct.md) type that contains fields of unmanaged types only and, in C# 7.3 and earlier, is not a constructed type (a type that includes at least one type argument) Beginning with C# 7.3, you can use the [`unmanaged` constraint](../../programming-guide/generics/constraints-on-type-parameters.md#unmanaged-constraint) to specify that a type parameter is a non-pointer unmanaged type. +Beginning with C# 8.0, a *constructed* struct type that contains fields of unmanaged types only is also unmanaged, as the following example shows: + +[!code-csharp[unmanaged constructed types](~/samples/csharp/language-reference/builtin-types/UnmanagedTypes.cs#ProgramExample)] + +A generic struct may be the source of both unmanaged and not unmanaged constructed types. The preceding example defines a generic struct `Coords` and presents the examples of unmanaged constructed types. The example of not an unmanaged type is `Coords`. It's not unmanaged because it has the fields of the `object` type, which is not unmanaged. If you want *all* constructed types to be unmanaged types, use the `unmanaged` constraint in the definition of a generic struct: + +[!code-csharp[unmanaged constraint in type definition](~/samples/csharp/language-reference/builtin-types/UnmanagedTypes.cs#AlwaysUnmanaged)] + ## C# language specification For more information, see the [Pointer types](~/_csharplang/spec/unsafe-code.md#pointer-types) section of the [C# language specification](~/_csharplang/spec/introduction.md). diff --git a/docs/csharp/whats-new/csharp-8.md b/docs/csharp/whats-new/csharp-8.md index 5b6cdc094ef37..8c2d5eb2a6070 100644 --- a/docs/csharp/whats-new/csharp-8.md +++ b/docs/csharp/whats-new/csharp-8.md @@ -1,7 +1,7 @@ --- title: What's New in C# 8.0 - C# Guide description: Get an overview of the new features available in C# 8.0. This article is up-to-date with preview 5. -ms.date: 09/02/2019 +ms.date: 09/04/2019 --- # What's new in C# 8.0 @@ -20,6 +20,7 @@ There are many enhancements to the C# language that you can try out already. - [Nullable reference types](#nullable-reference-types) - [Asynchronous streams](#asynchronous-streams) - [Indices and ranges](#indices-and-ranges) +- [Unmanaged constructed types](#unmanaged-constructed-types) - [Enhancement of interpolated verbatim strings](#enhancement-of-interpolated-verbatim-strings) > [!NOTE] @@ -441,6 +442,33 @@ var text = words[phrase]; You can explore more about indices and ranges in the tutorial on [indices and ranges](../tutorials/ranges-indexes.md). +## Unmanaged constructed types + +In C# 7.3 and earlier, a constructed type (a type that includes at least one type argument) cannot be an [unmanaged type](../language-reference/builtin-types/unmanaged-types.md). Starting with C# 8.0, a constructed value type is unmanaged if it contains fields of unmanaged types only. + +For example, given the following definition of the generic `Coords` type: + +```csharp +public struct Coords +{ + public T X; + public T Y; +} +``` + +the `Coords` type is an unmanaged type in C# 8.0 and later. Like for any unmanaged type, you can create a pointer to a variable of this type or [allocate a block of memory on the stack](../language-reference/operators/stackalloc.md) for instances of this type: + +```csharp +Span> coordinates = stackalloc[] +{ + new Coords { X = 0, Y = 0 }, + new Coords { X = 0, Y = 3 }, + new Coords { X = 4, Y = 0 } +}; +``` + +For more information, see [Unmanaged types](../language-reference/builtin-types/unmanaged-types.md). + ## Enhancement of interpolated verbatim strings Order of the `$` and `@` tokens in [interpolated](../language-reference/tokens/interpolated.md) verbatim strings can be any: both `$@"..."` and `@$"..."` are valid interpolated verbatim strings. In earlier C# versions, the `$` token must appear before the `@` token.