SIGN UP MEMBER LOGIN:    
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
share this article :
post comment
 

greatarticle thanks

Posted by Balamuruan B Jun 01, 2010
Become a Sponsor
PREMIUM SPONSORS
  • ceTE software specializes in components for dynamic PDF generation and manipulation. The DynamicPDF™ product line allows you to dynamically generate PDF documents, merge PDF documents and new content to existing PDF documents from within your applications.
    Finally – a virtual platform that delivers next-generation Windows Server 2008 Hyper-V virtualization technology from a managed hosting partner you can truly depend on. Visit www.maximumasp.com/max for a FREE 30 day trial. Hurry offer ends soon. Climb aboard the MaxV platform and take advantage of High Availability, Intelligent Monitoring, Recurrent Backups, and Scalability – with no hassle or hidden fees. As a managed hosting partner focused solely on Microsoft technologies since 2000, MaximumASP is uniquely qualified to provide the superior support that our business is built on. Unparalleled expertise with Microsoft technologies lead to working directly with Microsoft as first to offer IIS 7 and SQL 2008 betas in a hosted environment; partnering in the Go Live Program for Hyper-V; and product co-launches built on WS 2008 with Hyper-V technology.
6 Months Free & No Setup Fees ASP.NET Hosting!
Become a Sponsor