Start Debugging

Fix: CS9035 "Required member 'X' must be set in the object initializer" in C#

CS9035 means a member marked required was not assigned. Set it in the object initializer, or add a constructor annotated with [SetsRequiredMembers] that assigns every required member.

CS9035 fires at compile time when you create an instance of a type that has a required member, but that member is not assigned. The compiler wants every required field or property set before the object escapes construction. Fix it the direct way: add the member to the object initializer, for example new Person { Name = "Ada" }. If a constructor already assigns the member, tell the compiler by putting [SetsRequiredMembers] on that constructor so it stops demanding the initializer. This is verified against C# 14 on .NET 11; the required modifier and this diagnostic have behaved the same way since C# 11 on .NET 7.

The error in context

The full message names the exact member the compiler is missing:

error CS9035: Required member 'Person.Name' must be set in the object initializer or attribute constructor.

You will see one CS9035 per unset required member, so a type with three required properties and a bare new Person() produces three errors at once. It is a compile-time diagnostic, not a runtime exception: the build fails, nothing runs. That is the whole point of required, the check moved from a NullReferenceException you hit in production to a red squiggle you see in the editor.

Why this happens

The required modifier, introduced in C# 11, marks a field or property as mandatory at initialization time. When any expression constructs a new instance of the type, the compiler verifies that every required member is assigned, either through an object initializer or through a constructor that promises to set them. If it cannot prove that, it emits CS9035.

The key word is “prove.” The compiler does not run your code. It only trusts two things: a member you assign directly in the object initializer, and a constructor explicitly annotated with [SetsRequiredMembers]. A constructor that happens to assign the member in its body but lacks the attribute counts for nothing, the compiler will not read the body to figure that out. This is why the error survives even when your constructor clearly sets the value: you have to tell the compiler, not show it.

Three situations produce the error:

Minimal repro

The smallest type that triggers CS9035:

// .NET 11, C# 14
public class Person
{
    public required string Name { get; init; }
    public required string Email { get; init; }
    public int Age { get; init; }   // not required, optional
}

Every one of these constructions fails to compile:

// .NET 11, C# 14
var a = new Person();                        // CS9035 x2 (Name and Email)
var b = new Person { Name = "Ada" };         // CS9035 x1 (Email still missing)
var c = new Person { Age = 36 };             // CS9035 x2 (Name and Email)

Only when both required members are present does it build:

// .NET 11, C# 14 -- compiles
var ok = new Person { Name = "Ada", Email = "ada@example.com" };

Note that Age is left out and that is fine. required is per-member; optional members stay optional. The compiler cares only that the members carrying the required modifier are assigned.

Fix, in detail

Work through these in order. The first one is the answer in the vast majority of cases; the rest cover the situations where an initializer is not what you want.

1. Assign the required members in the object initializer

The intended fix is to set every required member at the call site:

// .NET 11, C# 14
var person = new Person
{
    Name = "Ada Lovelace",
    Email = "ada@example.com",
    // Age is optional, omit it freely
};

This is what required is for: the type’s contract says these fields are mandatory, and the initializer honours it. If you find yourself repeating the same values, that is a signal the type wants a constructor, which is the next fix.

2. Add a constructor annotated with [SetsRequiredMembers]

When a constructor already takes the values and assigns them, decorate it with System.Diagnostics.CodeAnalysis.SetsRequiredMembers. This attribute asserts to the compiler that the constructor initializes every required member, so callers no longer need an object initializer:

// .NET 11, C# 14
using System.Diagnostics.CodeAnalysis;

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

    [SetsRequiredMembers]
    public Person(string name, string email)
    {
        Name = name;
        Email = email;
    }
}

// now this compiles, no initializer needed
var person = new Person("Ada", "ada@example.com");

One sharp edge: [SetsRequiredMembers] is an assertion, not a verified guarantee. The compiler takes your word for it and does not check that the constructor actually assigns every required member. If you add the attribute but forget to set Email in the body, you get no CS9035 and no warning, just a null where you promised a value. Keep the attribute honest.

If you keep a parameterless constructor alongside the annotated one, callers of the parameterless version still need the initializer. The attribute only exempts the specific constructor it sits on.

3. Drop required if the member is not actually mandatory

If the member has a sensible default or is genuinely optional, it should not be required in the first place. Removing the modifier removes the obligation:

// .NET 11, C# 14
public class Person
{
    public required string Name { get; init; }
    public string Email { get; init; } = "";   // was required, now optional with a default
}

This is the right call surprisingly often. Reach for required only when there is no reasonable default and construction without the value would leave the object in an invalid state. Giving a property a default and dropping required is cleaner than forcing every call site to pass an empty string.

4. For records, use a positional or [SetsRequiredMembers] constructor

A positional record generates an init property per parameter, but those are not required by default. If you explicitly add a required property to a record with a primary constructor, the primary constructor does not automatically satisfy it, and you get CS9035 when you use the positional form. This trips people up because it looks like the constructor should count. See the design discussion in dotnet/csharplang #6780 for the reasoning. The fix is to either set the property in an initializer on top of the positional call, or add [SetsRequiredMembers] to a constructor that assigns it:

// .NET 11, C# 14
using System.Diagnostics.CodeAnalysis;

public record Product(string Sku)
{
    public required string Name { get; init; }

    [SetsRequiredMembers]
    public Product(string sku, string name) : this(sku) => Name = name;
}

// both work now
var withInit = new Product("A-100") { Name = "Widget" };
var withCtor = new Product("A-100", "Widget");

If you want the whole record’s construction to be enforced through the positional parameters, prefer plain init properties over required ones. Mixing positional records and required members is a source of confusion; decide which model the type uses. For a broader take on when a record earns its keep, see record vs class vs struct in C#.

Gotchas and variants

A handful of situations produce CS9035, or something that looks like it, for reasons that are not obvious from the message:

The mental model to keep: required moves a “you must provide this” rule from a runtime hope into a compile-time guarantee, and CS9035 is that guarantee doing its job. When you see it, the fix is always one of “provide the value at the call site” or “tell the compiler a constructor already provides it.” Decide which is true for the type, then either fill in the initializer or add [SetsRequiredMembers], and never reach for the attribute as a way to silence the error without actually setting the member.

Sources

Comments

Sign in with GitHub to comment. Reactions and replies thread back to the comments repo.

< Back