ARTICLE

How to: Set read-only fields outside constructors in C#

Posted by jinge Articles | C# Language May 19, 2010
In this article we will see how to set read-only fields outside constructors in C#.
Reader Level:

It's a well know rule that the readonly fields can only be set in the static constructors or auto constructors. But if we just have a requirement to set it outside the constructors, can this really be done?
 
The answer is yes, we can crack it by using Reflection. Actually, we can get the FieldInfo which is a wrapper class which contains all the information related to a field, and  it exposes SetValue interface to us which we can leverage. 
 
Suppose we have the following Person type:

public class Person
{
    private int age;
    private string sex;
    readonly private static string name;
    readonly private string job;
    static Person()
    {
        name = "initial name";
    }
    public Person()
    {
        age = 10;
        sex = "male";
        job = "none";
    }
    public int Age
    {
        get
        {
            return age;
        }
    }
    public string Job
    {
        get
        {
            return job;
        }
    }
    public static string Name
    {
        get
        {
            return name;
        }
    }
    public string Sex
    {
        get
        {
            return sex;
        }
    }
}

We can see that there's a static constructor and an auto constructor giving initial values for the fields, now in a consumption code, we may write the following code:

public void Main()
{
    Person p = new Person();
    Console.WriteLine(p.Job);
    Console.WriteLine(Person.Name);
    Console.WriteLine(p.Age);

    Type type = p.GetType();
    FieldInfo nameField = type.GetField("name", BindingFlags.NonPublic | BindingFlags.Static);
    nameField.SetValue(null, "NewName");
    FieldInfo jobField = type.GetField("job", BindingFlags.NonPublic | BindingFlags.Instance);
    jobField.SetValue(p, "New Job");
    FieldInfo ageField = type.GetField("age", BindingFlags.NonPublic | BindingFlags.Instance);
    ageField.SetValue(p, 20);
    Console.WriteLine(p.Job);
    Console.WriteLine(Person.Name);
    Console.WriteLine(p.Age);
}

With this, we can also see that the trick used above can also be applied in cracking the private field.

Sometimes, when we are using components by others, we may have less control with it. So knowing this trick will help you in handling certain type of cases.
 
By the way, if we don't know the declaration of the fields or methods, we can get it through Object Browser of Visual Studio.

Login to add your contents and source code to this article
post comment
     

Don't forget you can use out params to set readonly fields outside the constructor as well. Example here: http://www.adamjamesnaylor.com/2013/01/23/Setting-Readonly-Fields-From-Chained-Constructors.aspx

Posted by adam naylor Jan 23, 2013

greatarticle thanks

Posted by Balamuruan B Jun 01, 2010
COMMENT USING
PREMIUM SPONSORS
Over-C is a holistic consortium of communications and technology specialists. We build, deploy and market both business as well as consumer products and solutions.
SPONSORED BY
  • PDF reports have never been easier to create. With our included WYSIWYG Designer, you can layout your reports, set up your data source and let DynamicPDF ReportWriter do the rest.
Get Career Advice from Experts