Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

367
Views
Should it be possible to set a C# init-only property at run time?

I tried writing some C# code to create an init-only property. I was surprised to find that the property could be changed at run-time. Have I misunderstood the idea of immutability? I am using Visual Studio Community 16.9.3.

Sample code.

namespace TonyStachnicki.Windows {
    using System.Management.Automation;

    [Cmdlet(VerbsCommon.New, "Person")]
    public class NewPerson : Cmdlet {
        protected override void ProcessRecord() {
            var _Person = new Person {
                Name = "Jane Dough"
            };
            WriteObject(_Person);
        }
    }
    public class Person {
        public string Name { get; init; }
    }

}

Run time example.

PS D:\Users\Tony> ($Person = New-Person)

Name
----
Jane Dough

PS D:\Users\Tony> $Person.Name = "John Smith"
PS D:\Users\Tony> $Person

Name
----
John Smith

PS D:\Users\Tony> $Person.Name = "Jane Jones"
PS D:\Users\Tony> $Person

Name
----
Jane Jones

PS D:\Users\Tony>

The program behaves the same with this Person class.

    public class Person {
        public string Name {
            get  { return m_Name; } 
            init { m_Name = value; }
        }
        private readonly string m_Name;
    }

In this case the readonly modifier is also ignored.
I think most people would be surprised at the effect of the init-only feature.

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

Your C# code doesn't re-assign the value, so no C# rules were violated here. Whether powershell resects the rules is entirely up to powershell. Note:

  • the reflection API deliberately does not prevent access - this was so that serializers, ORMs etc worked without changes (and also so that the reflection API didn't need changes, which means it continues to work the same on older runtimes)
  • the more general IL access check depends on a "modreq" - but that is up to the relevant IL tools (usually a language compiler) to make decisions on; if a particular tool ignores "modreq", then: it ignores it
over 4 years ago · Santiago Trujillo Report

0

From this source : "When the init keyword is used, it restricts a property to only being set by a Constructor or during Nested Object Creation." That means that

var _Person = new Person {
                Name = "Jane Dough"
            };

is legal (since it uses nested object creation). This is unlike the pre-C# 9.0 case, where you could define the property without a setter. This allows initialization only in the constructor, but not in a nested object creation.

Therefore, if you define your Person class as:

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

your code would not compile (and you would need to provide a non-default constructor to your Person class to set Name to something)

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!