Skip to content

C# 8.0: unmanaged constructed types #14198

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 8 commits into from
Sep 5, 2019
Merged
Show file tree
Hide file tree
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
14 changes: 11 additions & 3 deletions docs/csharp/language-reference/builtin-types/unmanaged-types.md
Original file line number Diff line number Diff line change
@@ -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<T>` and presents the examples of unmanaged constructed types. The example of not an unmanaged type is `Coords<object>`. 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).
Expand Down
30 changes: 29 additions & 1 deletion docs/csharp/whats-new/csharp-8.md
Original file line number Diff line number Diff line change
@@ -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

Expand All @@ -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]
Expand Down Expand Up @@ -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<T>` type:

```csharp
public struct Coords<T>
{
public T X;
public T Y;
}
```

the `Coords<int>` 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<Coords<int>> coordinates = stackalloc[]
{
new Coords<int> { X = 0, Y = 0 },
new Coords<int> { X = 0, Y = 3 },
new Coords<int> { 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.