Since C# 7.0, C# language has introduced many new data types, type constructs and language features in type systems to improve performance, type safety and development efficiency. This article comprehensively compiles new content from C# 7.0 to C# 14.0 (as of April 2025, C# 14.0 is the preview version), including value tuples,Span<T>
、ReadOnlySpan<T>
、Memory<T>
、ReadOnlyMemory<T>
, nullable reference types, records, native size integers, record structures, inline arrays, and other enhancements (such as read-only structures, generic math support).
Version Overview
The following are the main contents of the type system added or enhanced in C# 7.0 to C# 14.0:
C# version | Added/enhanced content | Release year | describe |
---|---|---|---|
7.0 | Value Tuples | 2017 | Lightweight data structure, supporting multi-value return and destructuring |
7.2 | Span, ReadOnlySpan, read-only structure, reference structure | 2017 | High-performance memory operation and immutable/stack allocation structure |
8.0 | Nullable reference type, Memory, ReadOnlyMemory | 2019 | Null value security and managed memory blocks |
9.0 | Record, native size integer, initializer-specific type | 2020 | Value semantic reference types, native integers, and immutable properties |
10.0 | Record structure, global using directive | 2021 | Value type records and simplified type references |
11.0 | Required members, generic math support, file local types | 2022 | Forced initialization, generic operations, and type scope limitations |
12.0 | Inline arrays | 2023 | Fixed-size array structure, optimize performance |
13.0 | Parameter collection extension, reference structure interface support, some attributes | 2024 | Extend params, ref struct interface and partial property definitions |
14.0 |
field keywords, implicit span conversion,nameof Enhancement, lambda parameter modifier, partial member extension, empty condition assignment |
2025 | Enhanced attribute access, span usage, generic processing, lambda expression, partial type, and null value processing |
The following is detailed by version, each section contains feature tables, code examples, and analysis.
C# 7.0: Value Tuples
Feature Table
Type/Construction | describe | Main uses | Things to note |
---|---|---|---|
Value Tuples | Lightweight value type, supports multi-value return, named elements and deconstruction | Method returns multiple values and temporary data grouping | Value type, stack allocation; .NET Framework requires reference packages |
Overview
Value tuples are based on, allows methods to return multiple values, supports named elements and deconstruction, and simplifies data transfer.
grammar
-
statement: (type1, type2, ...) tupleName = (value1, value2, ...);
-
Named elements: (type1 name1, type2 name2, ...) tupleName = (value1, value2, ...);
-
Deconstruction: var (var1, var2, ...) = tupleName;
Sample code
public (int id, string name) GetPerson()
{
return (1, "Alice");
}
var person = GetPerson();
($"ID: {}, Name: {}");
// Deconstruction
var (id, name) = GetPerson();
($"ID: {id}, Name: {name}");
Applicable scenarios
-
The method returns multiple related values. -
Temporary data grouping without defining classes or structures. -
Deconstruct assignments and simplify the code.
Things to note
-
Value type, suitable for lightweight data. -
The .NET Framework project requires reference to the NuGet package.
C# 7.2: Span, ReadOnlySpan, read-only structure, reference structure
Feature Table
Type/Construction | describe | Main uses | Things to note |
---|---|---|---|
Span | Refers to continuous memory blocks, supporting read and write | High-performance array/memory operation | ref struct, stack allocation, life cycle limit |
ReadOnlySpan | Read-only continuous memory block reference | High-performance read-only operation | Same as above, memory boundary security needs to be ensured |
Readonly struct | Immutable structure, optimize performance | Immutable data structure | All instance fields must be read only |
Reference structure (ref struct) | Stack allocation structure | High-performance memory management | Can't box or implement as an interface |
Overview
Span<T>
andReadOnlySpan<T>
is a high-performance value type that represents continuous memory block references, suitable for array and native memory operations.readonly struct
Ensure that the structure is immutable,ref struct
Limit to stack allocation, supportSpan<T>
etc.
grammar
-
Span: Span<T> span = ();
-
ReadOnlySpan: ReadOnlySpan<T> readOnlySpan = ();
-
Read-only structure: readonly struct StructName { ... }
-
Quote Structure: ref struct StructName { ... }
Sample code
// Span<T> and ReadOnlySpan<T>
int[] numbers = [1, 2, 3, 4, 5];
Span<int> span = (1, 3);
span[0] = 10;
((", ", ())); // 10, 3, 4
ReadOnlySpan<char> text = "Hello".AsSpan();
((0, 2).ToString()); // He
// Read-only structure
readonly struct Point
{
public int X { get; init; }
public int Y { get; init; }
}
Point point = new() { X = 1, Y = 2 };
($"({}, {})"); // (1, 2)
// Quote Structure
ref struct Buffer
{
public Span<int> Data;
public Buffer(Span<int> data) => Data = data;
}
Buffer buffer = new(());
[0] = 10;
(numbers[0]); // 10
Applicable scenarios
-
High-performance string parsing and buffer processing. -
Immutable data structure (read-only structure). -
Avoid heap allocation (reference structure).
Things to note
-
Span<T>
andReadOnlySpan<T>
Not available for asynchronous methods. -
ref struct
Strict restrictions and need to manage life cycles.
C# 8.0: Nullable reference types, Memory, ReadOnlyMemory
Feature Table
Type/Construction | describe | Main uses | Things to note |
---|---|---|---|
Nullable reference type | Reference types can be marked as nullable, default is not null | Enhanced null value security | Need to enable nullable context to handle compiler warnings |
Memory | Hosted memory blocks, support reading and writing | Asynchronous and high-performance memory operations | Suitable for asynchronous scenarios, and requires management of life cycles |
ReadOnlyMemory | Read-only managed memory blocks | Read-only asynchronous memory operation | Same as above |
Overview
The nullable reference type passes?
The suffix specifies whether the reference type can be null, reducing null reference exceptions.Memory<T>
andReadOnlyMemory<T>
Represents a managed memory block and supports asynchronous scenarios.
grammar
-
Nullable reference type: string? nullable; string nonNullable;
-
Memory: Memory<T> memory = ();
-
ReadOnlyMemory: ReadOnlyMemory<T> readOnlyMemory = ();
Sample code
// nullable reference type
#nullable enable
string nonNullable = "Hello";
string? nullable = null;
if (nullable != null)
{
();
}
// Memory<T> and ReadOnlyMemory<T>
int[] numbers = [1, 2, 3, 4, 5];
Memory<int> memory = (1, 3);
Span<int> span = ;
span[0] = 10;
((", ", ())); // 10, 3, 4
ReadOnlyMemory<char> text= "Hello".AsMemory();
((0, 2).()); // He
Applicable scenarios
-
Enhanced null value security (nullable reference type). -
Asynchronous memory operation (Memory). -
ReadOnlyMemory.
Things to note
-
The nullable reference type needs to be enabled explicitly. -
Memory life cycle needs to be managed.
C# 9.0: Record, native size integer, initializer-specific type
Feature Table
Type/Construction | describe | Main uses | Things to note |
---|---|---|---|
Records | Reference type with value semantics, default immutable | Data modeling, value equality | Immutable by default, variable behavior can be added |
Native size integer (nint, nuint) | Native size integer, map IntPtr/UIntPtr | Native code interoperability | Platform dependencies need to be considered |
Init-only setters | Immutable properties after initialization | Immutable data model | Only assign values during initialization |
Overview
Records are reference types with value semantics, and equality is automatically achieved.nint
andnuint
Supports native size integers.init
Modifiers enhance attribute immutability.
grammar
-
Record: public record ClassName(type1 Property1, ...);
-
Native size integer: nint nativeInt; nuint nativeUInt;
-
init-only: public type Property { get; init; }
Sample code
// Record
public record Person(string FirstName, string LastName);
var person1 = new Person("Alice", "Smith");
var person2 = new Person("Alice", "Smith");
(person1 == person2); // True
var person3 = person1 with { LastName = "Johnson" };
(person3); // Person { FirstName = Alice, LastName = Johnson }
//Native size integer
nint nativeInt = 42;
nuint nativeUInt = 42u;
($"Native int: {nativeInt}, Native uint: {nativeUInt}");
// Special type for initializer
public class Student
{
public string Name { get; init; }
}
var student = new Student { Name = "Alice" };
(); // Alice
Applicable scenarios
-
Data transfer object (record). -
Native code interoperability (nint, nuint). -
Immutable data model (init-only).
Things to note
-
Records support inheritance and must maintain value semantics. -
Native size integer platform dependencies.
C# 10.0: Record structure, global using directive
Feature Table
Type/Construction | describe | Main uses | Things to note |
---|---|---|---|
Record Structs | Recording of value types, combining value semantics and performance | Small data structure | Value type, copy cost needs to be considered |
Global using command | Global import namespace | Simplify type references | Need to balance code readability |
Overview
Record structures extend record characteristics to value types, combining value semantics and performance. Globalusing
Simplify type references.
grammar
-
Record structure: public record struct StructName(type1 Property1, ...);
-
Global using: global using System;
Sample code
// Record structure
public record struct Point(int X, int Y);
var point1 = new Point(1, 2);
var point2 = new Point(1, 2);
(point1 == point2); // True
var point3 = point1 with { X = 3 };
(point3); // Point { X = 3, Y = 2}
// Global using (assuming it is already at the top of the file)
("Hello, World!"); // No need to use System explicitly
Applicable scenarios
-
Value type data modeling (record structure). -
Large project namespace management (global using).
Things to note
-
The cost of copying the record structure needs to be paid attention to. -
Global using should be used with caution.
C# 11.0: Required Members, Generic Mathematical Support, File Local Types
Feature Table
Type/Construction | describe | Main uses | Things to note |
---|---|---|---|
Required members | Force member initialization | Ensure the key fields are initialized | Need to be combined with the initializer or constructor |
Generic Mathematics Support | Static abstract interface members support generic operations | Generic Algorithm Library | Requires runtime support (.NET 7+) |
File local type (file modifyer) | Restrict type scope to file | Isolation Assistance Type | File scope only |
Overview
required
Modifier forces member initialization. Generic mathematics supports numerical operations through interfaces.file
Modifiers limit type scope.
grammar
-
Required Members: public required type Property { get; set; }
-
Generic Mathematics: interface INumber<T> { static abstract T operator +(T, T); }
-
File local type: file class ClassName { ... }
Sample code
// Required Member
public class Person
{
public required string Name { get; set; }
}
var person = new Person { Name = "Alice" };
(); // Alice
// Generic Math Support
public interface INumber<T> where T : INumber<T>
{
static abstract T Add(T left, T right);
}
public readonly struct MyNumber : INumber<MyNumber>
{
public int Value { get; init; }
public MyNumber(int value) => Value = value;
public static MyNumber Add(MyNumber left, MyNumber right) => new( + );
}
MyNumber a = new(1);
MyNumber b = new(2);
var result = (a, b);
(); // 3
// File local type
file class Helper
{
public static void Log(string message) => (message);
}
("Test");
Applicable scenarios
-
API design (required members). -
Generic numerical calculation (generic mathematics). -
Code generation (file local type).
Things to note
-
Required members need to be explicitly initialized. -
Generic mathematics requires runtime support.
C# 12.0: Inline Arrays
Feature Table
Type/Construction | describe | Main uses | Things to note |
---|---|---|---|
Inline Arrays | Fixed-size array structure, stack allocation | High performance fixed-size arrays | Fixed size, only within the structure |
Overview
Inline array through[InlineArray]
Features define fixed-size array structures to optimize performance.
grammar
[InlineArray(length)]
public struct StructName
{
private elementType _element0;
}
Sample code
[InlineArray(10)]
public struct Buffer
{
private int _element0;
}
Buffer buffer = new();
buffer[0] = 1;
buffer[9] = 10;
(buffer[0]); // 1
Applicable scenarios
-
High performance computing. -
Replaces unsafe fixed buffers.
Things to note
-
Fixed size, not adjustable during runtime.
C# 13.0: Parameter collection extension, reference structure interface support, some attributes
Feature Table
Type/Construction | describe | Main uses | Things to note |
---|---|---|---|
Parameter set extension (params Span, etc.) | Extended params support Span, etc. | High performance parameter transfer | Span life cycle needs to be ensured |
Reference structure interface support | Allow ref struct to implement interfaces | Extend ref struct capability | Still subject to ref struct restrictions |
Partial properties | Support partial attributes of partial type | Code generation | Make sure that the definition is consistent |
Overview
Parameter collection extension supportSpan<T>
etc.ref struct
Interfaces can be implemented. Some properties support sub-file definitions.
grammar
-
Parameter set: void Method(params Span<T> spans);
-
Reference structure interface: ref struct StructName : IInterface { ... }
-
Some properties: public partial type Property { get; set; }
Sample code
// Parameter set extension
public void Process(params Span<int> spans)
{
foreach (var span in spans)
((", ", ()));
}
int[] numbers = [1, 2, 3];
Process((0, 2), (2, 1)); // 1, 2 and 3
// Reference structure interface support
public interface IBuffer
{
void Process();
}
ref struct Buffer: IBuffer
{
public Span<int> Data;
public Buffer(Span<int> data) => Data = data;
public void Process() => Data[0] = 10;
}
Buffer buffer = new(());
();
(numbers[0]); // 10
// Some attributes
public partial class Person
{
public partial string Name { get; set; }
}
public partial class Person
{
public partial string Name { get => _name; set => _name = value; }
private string _name;
}
var person = new Person { Name = "Alice" };
(); // Alice
Applicable scenarios
-
High performance parameter transfer (parameter set). -
Extended ref struct
(Interface support). -
Code generation (partial properties).
Things to note
-
Parameter collections need to manage the Span life cycle. -
Some attributes need to be consistent.
C# 14.0:field
keywords, implicit span conversion,nameof
Enhancement, lambda parameter modifier, partial member extension, empty condition assignment
Feature Table
Type/Construction | describe | Main uses | Things to note |
---|---|---|---|
field Keywords |
Allow direct access to the backing field in the property accessor | Simplify property implementation | It may conflict with existing field names and must be used@field or distinguish |
Implicit span conversion | supportSpan<T> 、ReadOnlySpan<T> Implicit conversion to arrays |
Use span types more naturally | Pay attention to the life cycle of span |
nameof Support unbound generics |
allownameof Use unbound generic types, such asnameof(List<>)
|
Get type name in generic programming | - |
lambda parameter modifier | Allow lambda parameters to be usedref 、out etc modifier, no need to specify type |
Enhance the flexibility of lambda expressions |
params Still need to specify the type |
partial constructors and events | Extend partial members to instance constructors and events | Separate definitions and implementations, suitable for code generation | Make sure that defining and implementing statements are consistent |
Empty condition assignment | Allow to use on the left side of the assignment?. and?[] , assign only when the left side is not null |
Simplify null checking | Not supported++ and--
|
Overview
C# 14.0 (expected to be released with .NET 10 in 2025 and previewed as of April 2025) introduces a range of language features designed to improve development efficiency and code readability, includingfield
Keywords, implicit span conversion,nameof
Enhancement, lambda parameter modifier, partial member extension, and null condition assignment. Although new data types are not introduced, these features significantly enhance the usage of existing types.
field
Keywords
Overview
field
Keywords allow direct access to compiler-generated backing fields in the property accessor without explicit declaration.
Sample code
public class Person
{
public string Name
{
get => field;
set => field = value?.Trim();
}
}
var person = new Person { Name = " Alice " };
(); // Alice
Applicable scenarios
-
Simplify property implementation, especially when processing setters are required.
Things to note
-
If the class already has a name field
fields, need to be used@field
ordistinguish.
-
As a preview feature of C# 13.0, C# 14.0 is officially supported, see the field keyword for details.
Implicit span conversion
Overview
C# 14.0 isSpan<T>
andReadOnlySpan<T>
Implicit conversion with arrays is provided to make its use more natural.
Sample code
Span<int> span = new int[] {1, 2, 3};
int[] array = ();
((", ", array)); // 1, 2, 3
Applicable scenarios
-
In high-performance scenarios, reduce explicit conversions. -
Interact with array and span types.
Things to note
-
You need to ensure the life cycle management of the span, see Span conversion for details.
nameof
Support unbound generics
Overview
allownameof
The operator uses unbound generic types.
Sample code
string listName = nameof(List<>);
(listName); // List
Applicable scenarios
-
In generic programming, get the type name.
Things to note
-
Simple but powerful enhancement, suitable for reflective scenes.
lambda parameter modifier
Overview
Allows to add modifiers to parameters in lambda expressions, such asref
、out
etc, no need to specify the type.
Sample code
var increment = (ref int x) => x++;
int num = 5;
increment(ref num);
(num); // 6
Applicable scenarios
-
External variables need to be modified in lambda.
Things to note
-
params
You still need to specify the type, see the lambda expression for details.
partial constructors and events
Overview
Extend partial members to instance constructors and events, allowing for decoupling of definitions and implementations in partial types.
Sample code
//
public partial class MyClass
{
public partial MyClass(int x);
public partial event EventHandler MyEvent;
}
//
public partial class MyClass
{
public partial MyClass(int x) { }
public partial event EventHandler MyEvent;
}
Applicable scenarios
-
Code generation scenarios, such as UI designer.
Things to note
-
It is necessary to ensure that defining and implementing declarations are consistent, see the partial member for details.
Empty condition assignment
Overview
Allows to use on the left side of the assignment statement?.
and?[]
, only if the left side is not null.
Sample code
string? text = null;
text?.Length= 5; // No assignment is performed
List<int>? list = null;
list?[0]= 10; // No assignment is performed
list = new List<int> { 0 };
list?[0] = 10; // Execute assignment, list[0] = 10
(list[0]); // 10
Applicable scenarios
-
Simplify null checking and avoid NullReferenceException.
Things to note
-
Not supported ++
and--
For operation, see the null condition assignment for details.
Conclusion
The new contents of the type system from C# 7.0 to C# 14.0 cover data types such as value tuples, Span, ReadOnlySpan, Memory, ReadOnlyMemory, nullable reference types, records, native size integers, record structures, inline arrays, etc., as well as read-only structures, reference structures, required members, generic math support and other enhancements. C# 14.0 passedfield
Keywords, implicit span conversion and other features further optimize the usage of existing types. These features meet a wide range of needs from high-performance memory management to type-safe modeling. Senior C# engineers can select types based on the scene, such as using Span to optimize performance and record modeling data. Since C# 14.0 is still in the preview stage, it is recommended to follow dotnet/roslyn for the latest updates.