Search code examples
c#constructorpropertiesinit-only

Setting init-only properties when using Activator.CreateInstance


C# 9.0 introduced init-only class properties feature but they can't be used when creating instances by class type with Activator.CreateInstance. A simplistic example:

class Person
{
    public string Name { get; init; }
}

void Test()
{
    Person person = (Person)Activator.CreateInstance(typeof(Person));
    person.Name = "Bob"; // Doesn't work
}

Looking for some solution other than using constructor arguments (too many of them).


Solution

  • Init properties are settable only in the following contexts:

    • During an object initializer
    • During a with expression initializer
    • Inside an instance constructor of the containing or derived type, on this or base
    • Inside the init accessor of any property, on this or base
    • Inside attribute usages with named parameters

    In turn, Object Initialization is simply syntactic sugar to set the instance properties or fields without directly invoking the constructor, and essentially transforms from

    Person person = new Person { Name = "Bob" };
    

    to

    Person person2 = new Person();
    person2.Name = "test";
    Person person = person;
    

    When using Activator.CreateInstance, you bypass this syntactic sugar. That said, if you are already using Activator.CreateInstance, you are potentially comfortable taking additional reflection hits. You can simply call PropertyInfo.SetValue to set the values after object creation:

    Person person = (Person)Activator.CreateInstance(typeof(Person));
        
    person.GetType().GetProperty("Name").SetValue(person, "Bob");
    

    Alternatively, you can create constructors and pass the values to the constructor.