Back to Blog
C#

C# SetsRequiredMembers: Constructor Initialization

c# setsrequiredmembers: Learn how the SetsRequiredMembers attribute in C# marks constructors that initialize all required members, and when to apply it.

C#Required MembersConstructorCompiler Attributes.NET
Illustration of a C# constructor marked with SetsRequiredMembers attribute ensuring required members are initialized.

c# setsrequiredmembers requires a clear understanding of the core syntax, runtime behavior, and practical implementation patterns demonstrated in the examples below.

Starting with C# 11, the required modifier lets you declare that a field or property must be initialized when an object is created. The compiler enforces this by requiring callers to use an object initializer for those members. But when you provide a constructor that already sets every required member, forcing callers to repeat that initialization is redundant. The SetsRequiredMembers attribute tells the compiler that a constructor takes responsibility for initializing all required members, so callers can use that constructor without an object initializer.

The Problem: Required Members and Object Initializers

Consider a class with a required property:

public class Person { public required string Name { get; init; } public required int Age { get; init; } }

Without any constructor, callers must initialize both members:

var person = new Person { Name = "Alice", Age = 30 };

If you add a constructor that sets these values, you might expect callers to use it directly:

public Person(string name, int age) { Name = name; Age = age; }

But the compiler still requires the object initializer, because it does not know whether the constructor actually sets all required members. The call new Person("Alice", 30) fails to compile with an error like CS9035: Required member 'Person.Age' must be set in the object initializer or attribute 'SetsRequiredMembers' must be set in the constructor.

Applying SetsRequiredMembers to a Constructor

The SetsRequiredMembers attribute is applied to a constructor to declare that it initializes all required members. The constructor must actually assign every required member; otherwise the compiler will issue a warning.

using System.Diagnostics.CodeAnalysis; public class Person { public required string Name { get; init; } public required int Age { get; init; } [SetsRequiredMembers] public Person(string name, int age) { Name = name; Age = age; } }

Now callers can construct the object without an object initializer:

var person = new Person("Alice", 30);

The attribute is a compile-time signal. It does not affect runtime behavior; it only suppresses the requirement for an object initializer.

How the Compiler Enforces Required Members

When a constructor is marked with SetsRequiredMembers, the compiler assumes that all required members are initialized by that constructor. If the constructor does not assign a required member, the compiler emits a warning (CS9035 or similar) to indicate that the required member might not be set. The attribute does not perform runtime validation; it is purely a compile-time contract.

The attribute can be applied to any constructor, including parameterless constructors, as long as the constructor sets all required members. If a required member is not assigned in the constructor body, the warning appears, and the attribute is effectively lying to the compiler.

When to Use SetsRequiredMembers

Use SetsRequiredMembers when you have a constructor that genuinely initializes every required member. This is common for DTOs, domain entities, and configuration objects where the constructor is the primary way to create instances. It removes the need for callers to repeat the initialization logic in an object initializer, which reduces duplication and makes the intent clearer.

The attribute is especially useful when the constructor performs validation or transformation of the input parameters before assigning the required members. For example:

public class Temperature { public required double Celsius { get; init; } [SetsRequiredMembers] public Temperature(double fahrenheit) { Celsius = (fahrenheit - 32) * 5 / 9; } }

Here the required member is set through a calculation, and the attribute tells the compiler that the constructor handles it.

Limitations and Common Pitfalls

The attribute is a promise, not a guarantee. If you mark a constructor with SetsRequiredMembers but forget to assign a required member, the compiler warns, but the code still compiles. At runtime, the required member will have its default value, which can lead to null references or incorrect behavior. Always ensure the constructor assigns every required member.

Another pitfall is using the attribute on a constructor that calls a virtual method or a helper that might not set the required members. The compiler cannot verify that the helper actually assigns the member, so you must be certain the assignment happens.

The attribute cannot be applied to a primary constructor of a class in the same way? Actually, primary constructors in C# 12 have different behavior. But we should be careful. We can mention that the attribute is not needed for primary constructors because they automatically set required members? Actually, we need to verify. We should not invent. We can say: "For primary constructors introduced in C# 12, the compiler automatically treats the parameters as assignments to required members if they are used to initialize them, so the attribute is not required." But that might be version-specific. We can mention that the attribute is for explicit constructors.

We'll keep it general.

Inheritance and Derived Types

When a base class has required members, derived classes must also initialize them. If a base constructor is marked with SetsRequiredMembers, derived constructors do not automatically inherit that behavior. A derived constructor must either call the base constructor (which sets the base required members) and also set its own required members, or it must also be marked with SetsRequiredMembers if it sets all required members itself.

Example:

public class Employee : Person { public required string Department { get; init; } [SetsRequiredMembers] public Employee(string name, int age, string department) : base(name, age) { Department = department; } }

Here the base constructor is called, which sets Name and Age, and the derived constructor sets Department. The attribute on the derived constructor tells the compiler that all required members are initialized, including those from the base class.

If the derived constructor does not set a required member from the base class, the compiler will warn, even if the base constructor is marked.

Alternatives to SetsRequiredMembers

If you prefer not to use the attribute, you can keep the object initializer requirement. This is useful when you want to force callers to explicitly name the members, which can improve readability for objects with many optional or required fields. Another alternative is to use factory methods that internally use object initializers, but then the factory method must be marked with SetsRequiredMembers if it returns an instance without an object initializer? Actually, factory methods can use new with object initializer internally, so they don't need the attribute. But if the factory method returns an instance created via a constructor that doesn't set all required members, you'd need the attribute on that constructor.

The choice depends on whether you want to enforce explicit member initialization at the call site or centralize it in a constructor.

Maintainability and Compatibility Considerations

SetsRequiredMembers is a compile-time feature. It has no runtime overhead and does not affect serialization, reflection, or performance. However, it does create a contract that must be maintained: if you add a new required member to a class, every constructor marked with SetsRequiredMembers must be updated to initialize it. The compiler will warn if you forget, but the warning is easy to miss if you are not treating warnings as errors.

The attribute is available in .NET 7 and later with C# 11. If you are targeting older frameworks, you need to use a polyfill or avoid required members altogether. Since the attribute is in the System.Diagnostics.CodeAnalysis namespace, it is part of the BCL, so it is available in .NET 7+.

In a codebase that uses required members extensively, SetsRequiredMembers helps keep constructors usable without forcing callers to use object initializers. It is a useful tool when the constructor is the canonical way to create an instance and you want to enforce invariants during construction.

c# setsrequiredmembers: Practical Usage and Code Examples | RYUSLOG DEV