C# public variable as writeable inside the class but readonly outside the class

27,836

Solution 1

Don't use a field - use a property:

class Foo
{
    public string Bar { get; private set; }
}

In this example Foo.Bar is readable everywhere and writable only by members of Foo itself.

As a side note, this example is using a C# feature introduced in version 3 called automatically implemented properties. This is syntactical sugar that the compiler will transform into a regular property that has a private backing field like this:

class Foo
{
    [CompilerGenerated]
    private string <Bar>k__BackingField;

    public string Bar
    {
        [CompilerGenerated]
        get
        {
            return this.<Bar>k__BackingField;
        }
        [CompilerGenerated]
        private set
        {
            this.<Bar>k__BackingField = value;
        }
    }
}

Solution 2

public class Foo
{
  public string Bar { get; private set; } 
}

Solution 3

You have to use a property for this. If you are fine with an automatic getter/setter implementation, this will work:

public string SomeProperty { get; private set; }

Note that you should not expose fields as public anyway, except in some limited circumstances. Use a property instead.

Solution 4

Sure. Make it a property, and make the setter private:

public Int32 SomeVariable { get; private set; }

Then to set it (from within some method in the class):

SomeVariable = 5;

Solution 5

Use a private variable and expose a public property.

class Person
{
  private string name;

  public string Name
  {
    get
    {
      return name;
    }
  }
}
Share:
27,836

Related videos on Youtube

MikeTWebb
Author by

MikeTWebb

I am a C# .Net/SQL/Oracle/Web developer. Also experienced in Business Analysis and Customer Interaction.

Updated on September 01, 2020

Comments

  • MikeTWebb
    MikeTWebb almost 4 years

    I have a .Net C# class where I need to make a variable public. I need to initialize this variable within a method (not within the constructor). However, I don't want the variable to be modifieable by other classes. Is this possible?

    • 3Dave
      3Dave over 13 years
      And the award for quickest question to 5 answers goes to...
  • JoeMjr2
    JoeMjr2 over 8 years
    But what if it is a reference type instead of a value type? Couldn't another class read the reference and then modify properties of the object that it points to?
  • usefulBee
    usefulBee about 7 years
    This won't work inside a method because it will be a read-only property.
  • rbm
    rbm almost 7 years
    This doesn't look good. You're calling fo.SomeBar.SomeValue = "Changed it!"; which does not do the assignment nor does it exception. If this was real code, it'd be a nightmare to debug. You should make things immutable so that you can't even compile or you should throw an exception.
  • kkCosmo
    kkCosmo almost 7 years
    This is a good point. How would you change it, so that SomeValue can still be changed by his owner but not by reference?
  • rbm
    rbm almost 7 years
    Look at the other answers, private set; is the most common way. Your example has effectively two classes, so you'd need to control the Fo.Bar and the Bar.SomeValue and make them immutable.
  • kkCosmo
    kkCosmo almost 7 years
    But that is beside the point. JoeMjr2 pointed out (in the comment of the top answer) that that works for value types, but that you still could modify the variables of a reference type. Hence my example with two classes. Making SomeValue private would not allow Fo the modification MikeTWebb asked for.
  • rbm
    rbm almost 7 years
    Not if you make the class immutable, i.e. set the values in constructor.
  • kkCosmo
    kkCosmo almost 7 years
    Depending on the needs of 'Fo' and the complexity of 'Bar' this has benefits. I agree. In that case the constructor of 'Bar' would take the value for 'SomeValue' and 'SomeValue' would be defined with e.g. a private setter. I will add it as third example.
  • Do-do-new
    Do-do-new over 5 years
    They can. For instance even in this case List's Add can be called, if List is a member. I had to deal with it with List (of course it is only one use-case of a reference) and ended-up doing ReadOnlyCollection member with getter only and private variable - a list.