Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 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
1 change: 1 addition & 0 deletions docs/core/compatibility/10.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ If you're migrating an app to .NET 10, the breaking changes listed here might af

| Title | Type of change | Introduced version |
|-------|-------------------|--------------------|
| [Disallow loading non-Explicit types with explicit field offsets](interop/10.0/explicit-field-offset-validation.md) | Binary incompatible/behavioral change | Preview 4 |
| [Single-file apps no longer look for native libraries in executable directory](interop/10.0/native-library-search.md) | Behavioral change | Preview 6 |
| [Specifying DllImportSearchPath.AssemblyDirectory only searches the assembly directory](interop/10.0/search-assembly-directory.md) | Behavioral change | Preview 5 |

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
---
title: "Breaking change: Disallow loading non-Explicit types with explicit field offsets"
description: "Learn about the breaking change in .NET 10 where the runtime enforces stricter validation for type layouts and throws TypeLoadException if non-explicit layout types specify explicit field offsets."
ms.date: 10/13/2025
ai-usage: ai-assisted
---

# Disallow loading non-Explicit types with explicit field offsets

Starting in .NET 10 Preview 4, the .NET runtime enforces stricter validation for type layouts. Specifically, the runtime now throws a <xref:System.TypeLoadException> if a type with a non-explicit layout (for example, `Auto` or `Sequential`) specifies explicit field offsets using the <xref:System.Runtime.InteropServices.FieldOffsetAttribute>. This change aligns the runtime's behavior with the ECMA-335 specification, which only permits explicit field offsets for types with an `Explicit` layout.

## Version introduced

.NET 10 Preview 4

## Previous behavior

In earlier versions of .NET, the runtime ignored explicit field offsets on types with `Auto` or `Sequential` layouts. For example:

```csharp
using System;
using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential)]
public struct MyStruct
{
[FieldOffset(0)] // Ignored in .NET versions prior to 10 Preview 4
public int Field1;

[FieldOffset(4)] // Ignored in .NET versions prior to 10 Preview 4
public int Field2;
}

class Program
{
static void Main()
{
Console.WriteLine("Struct loaded successfully.");
}
}
```

The above code would execute without error, and the `[FieldOffset]` attributes would be ignored.

## New behavior

Starting in .NET 10 Preview 4, the runtime enforces the ECMA-335 specification and throws a <xref:System.TypeLoadException> if a type with `Auto` or `Sequential` layout specifies explicit field offsets. The following code now throws an exception:

```csharp
using System;
using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential)]
public struct MyStruct
{
[FieldOffset(0)] // Causes a TypeLoadException in .NET 10 Preview 4 and later
public int Field1;

[FieldOffset(4)] // Causes a TypeLoadException in .NET 10 Preview 4 and later
public int Field2;
}

class Program
{
static void Main()
{
Console.WriteLine("Struct loaded successfully.");
}
}
```

**Exception thrown:**

```output
System.TypeLoadException: Explicit field offsets are not allowed on types with Sequential or Auto layout.
```

## Type of breaking change

This change can affect [binary compatibility](../../categories.md#binary-compatibility) and is a [behavioral change](../../categories.md#behavioral-change).

## Reason for change

This change was introduced to align the .NET runtime with the ECMA-335 specification, which explicitly disallows explicit field offsets on types with `Auto` or `Sequential` layouts. The previous behavior of ignoring these offsets was non-compliant and could lead to unexpected behavior or incorrect assumptions about memory layout.

## Recommended action

To resolve this issue, update your code to use `LayoutKind.Explicit` for types that specify explicit field offsets. For example:

```csharp
using System;
using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Explicit)] // Use Explicit layout
public struct MyStruct
{
[FieldOffset(0)]
public int Field1;

[FieldOffset(4)]
public int Field2;
}

class Program
{
static void Main()
{
Console.WriteLine("Struct loaded successfully.");
}
}
```

Alternatively, if explicit field offsets aren't required, remove the <xref:System.Runtime.InteropServices.FieldOffsetAttribute> attributes and rely on the default behavior of `Sequential` or `Auto` layout.

## Affected APIs

- <xref:System.Runtime.InteropServices.StructLayoutAttribute?displayProperty=fullName>
- <xref:System.Runtime.InteropServices.FieldOffsetAttribute?displayProperty=fullName>

## See also

- [ECMA-335 specification](https://www.ecma-international.org/publications-and-standards/standards/ecma-335/)
- [Customize structure marshalling](../../../../standard/native-interop/customize-struct-marshalling.md)
2 changes: 2 additions & 0 deletions docs/core/compatibility/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ items:
href: globalization/10.0/version-override.md
- name: Interop
items:
- name: Disallow loading non-Explicit types with explicit field offsets
href: interop/10.0/explicit-field-offset-validation.md
- name: Single-file apps no longer look for native libraries in executable directory
href: interop/10.0/native-library-search.md
- name: Specifying DllImportSearchPath.AssemblyDirectory only searches the assembly directory
Expand Down
Loading