Skip to content

Latest commit

 

History

History
30 lines (18 loc) · 2.78 KB

readonly-struct.md

File metadata and controls

30 lines (18 loc) · 2.78 KB

Declare readonly structs for immutable value types

The intent of the Point3D structure is that it is immutable. It's public interface appears to be immutable. However, the compiler can't discern that intent, and that has implications. Most importantly, the compiler can't help you enforce that design intent. A human reader can look at the code and determine that you intend it to be immutable, but that's only a convention. In addition, the compiler must assume that a Point3D is not immutable. That means the compiler will create a defensive copy when a readonly reference to a Point3D accesses a member. Let's look at the Point3D structure one more time:

Change the declaration of Point3D by adding the readonly modifier:

public readonly struct Point3D

This has two advantages. First, it exposes any accidental modifications of the struct. You can see this in the error in ComputeDistance. Refactor that method, and remove the distance member field so that Point3D struct us completely immutuble. Second, the compiler can take advantage of the knowledge that Point3D is immutable to skip any defensive copies.

Declaring a struct using the readonly modifier informs the compiler that your intent is to create an immutable type. The compiler enforces that design decision with the following rules:

  • All field members must be readonly
  • All properties must be read-only, including auto-implemented properties.

These two rules are sufficient to ensure that no member of a readonly struct modifies the state of that struct. The struct is immutable. Declare your structs as readonly whenever your design intent is to create an immutable value type. Any performance improvements are an added benefit. The readonly struct clearly expresses your design intent.

ref struct types

A related language feature is the ability to declare a value type that must be constrained to a single stack frame. This restriction enables the compiler to make several optimizations. The primary motivation for this feature was Span<T> and related structures. You'll achieve performance improvements from these enhancements by using new and updated .NET APIs that make use of the Span<T> type. You can combine these features to create ref readonly struct types, such as ReadonlySpan<T>.