C# tutorials > Modern C# Features > C# 6.0 and Later > What are inline arrays in C# 12 and when might you use them?
What are inline arrays in C# 12 and when might you use them?
Inline Arrays in C# 12: Enhancing Performance and Interoperability
C# 12 introduces a powerful new feature called inline arrays. This feature aims to improve performance in specific scenarios, especially when dealing with interop (interacting with native code) and high-performance data structures. This tutorial explores inline arrays, their purpose, syntax, and practical applications.
Understanding Inline Arrays
Inline arrays are a way to create arrays where the array elements are laid out contiguously in memory directly within a structure. This is different from regular C# arrays, which are reference types and reside on the heap. Inline arrays are value types, providing a more direct memory representation. This direct memory layout can offer performance benefits by reducing indirection and improving cache locality, particularly when interacting with unmanaged code or working with large datasets where memory layout is critical.
Syntax and Declaration
To define an inline array, you need to use the Key points:[InlineArray]
attribute from the System.Runtime.CompilerServices
namespace. This attribute specifies the size of the array. The array elements are then implicitly available as fields within the struct.
[InlineArray]
attribute takes an integer argument, representing the array size._element0
), but it must exist.array[0]
).
using System.Runtime.CompilerServices;
[InlineArray(10)]
public struct MyInlineArray
{
private int _element0; // This field is REQUIRED. Name is arbitrary.
}
public class Example
{
public static void Main(string[] args)
{
MyInlineArray array = new MyInlineArray();
array[0] = 10;
array[5] = 50;
Console.WriteLine(array[0]); // Output: 10
Console.WriteLine(array[5]); // Output: 50
}
}
Concepts Behind the Snippet
The provided code demonstrates the fundamental concept of inline arrays. The The code then shows how to access and modify the elements of the inline array using the indexer. This allows working with the inline array in a way that's syntactically similar to regular arrays.MyInlineArray
struct declares an inline array of 10 integers. The _element0
field serves as the first element and backing store. The [InlineArray(10)]
attribute informs the compiler to treat this struct as an inline array with a size of 10.
Real-Life Use Case Section
A common use case for inline arrays is representing fixed-size data structures, such as vectors or matrices, especially in graphics or physics engines. The example above shows how to define a This is also useful in interoperability scenarios. Imagine you have a C library with a function that expects a pointer to an array of 3 floats representing a vector. With inline arrays, you can directly pass a Vector3
struct using an inline array of three floats. This avoids the overhead of creating a separate array object on the heap and improves memory locality, which can be crucial for performance in these types of applications.Vector3
struct to that function without needing to copy the data into a separate managed array.
// Example: Representing a fixed-size vector
using System.Runtime.CompilerServices;
[InlineArray(3)]
public struct Vector3
{
private float _element0;
public Vector3(float x, float y, float z)
{
this[0] = x;
this[1] = y;
this[2] = z;
}
public float X { get { return this[0]; } set { this[0] = value; } }
public float Y { get { return this[1]; } set { this[1] = value; } }
public float Z { get { return this[2]; } set { this[2] = value; } }
public override string ToString()
{
return $"({X}, {Y}, {Z})";
}
}
public class Example
{
public static void Main(string[] args)
{
Vector3 v = new Vector3(1.0f, 2.0f, 3.0f);
Console.WriteLine(v); // Output: (1, 2, 3)
v.X = 5.0f;
Console.WriteLine(v); // Output: (5, 2, 3)
}
}
Best Practices
Interview Tip
When discussing inline arrays in an interview, emphasize their purpose for performance optimization, especially in scenarios involving unmanaged code or low-latency applications. Be prepared to explain their memory layout benefits and the tradeoffs involved in using them. Mention their introduction in C# 12 and their use cases in game development or scientific computing.
When to Use Them
Consider using inline arrays when:
Memory Footprint
The memory footprint of an inline array is determined by the size of the underlying element type multiplied by the array size. For example, a [InlineArray(10)] struct MyInlineArray { private int _element0; }
will occupy 40 bytes of memory (10 elements * 4 bytes per int). This is typically more compact than a regular C# array of 10 integers, because that array is a reference type that points to data stored on the heap, along with the overhead associated with the array object itself.
Alternatives
Alternatives to inline arrays include:
System.Span<T>
and System.Memory<T>
: Provide a way to work with contiguous regions of memory without creating new arrays. Useful for slicing arrays and working with memory buffers. These can wrap existing arrays.
Pros
Cons
[InlineArray]
attribute and the underlying memory layout.
FAQ
-
Are inline arrays reference types or value types?
Inline arrays are value types (structs). -
What happens if I try to access an element outside the bounds of an inline array?
You will get anIndexOutOfRangeException
, just like with regular C# arrays. -
Can I use inline arrays with generic types?
Yes, you can use inline arrays with generic types, but the element type must be known at compile time. -
Is the private field `_element0` mandatory?
Yes, the private field that is the backing store for the inline array is mandatory. The name is arbitrary, but it must exist.