Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

When setting a value to a variable inside of a class most of the time we are presented with two options:

private string myValue;
public string MyValue
{
   get { return myValue; }
   set { myValue = value; }
}

Is there a convention that determines how we should assign values to variables inside of our classes? For example if I have a method inside the same class should I assign it using the property or using the private variable. I've seen it done both ways, so I was wondering if this is a choice or performance is a factor (minor, probably).

share|improve this question
add comment

8 Answers 8

up vote 16 down vote accepted

I would take it a step further, and bring it to 3 cases. Although there are variations on each, this is the rules I use the majority of the time when C# programming.

In case 2&3, always go to the Property Accessor (not the field variable). And in case 1, you are saved from even having to make this choice.

1.) Immutable property (passed in to constructor, or created at construction time). In this case, I use a field variable, with a read-only property. I choose this over a private setter, since a private setter does not guarantee immutability.

public class Abc
{ 
  private readonly int foo;

  public Abc(int fooToUse){
    foo = fooToUse;
  }

  public int Foo { get{ return foo; } }
}

2.) POCO variable. A simple variable that can get/set at any public/private scope. In this case I would just use an automatic property.

public class Abc
{ 
  public int Foo {get; set;}
}

3.) ViewModel binding properties. For classes that support INotifyPropertyChanged, I think you need a private, backing field variable.

public class Abc : INotifyPropertyChanged
{
  private int foo;

  public int Foo
  {
    get { return foo; }
    set { foo = value;  OnPropertyChanged("foo"); }
  }
}
share|improve this answer
1  
+1 for MVVM example. Actually that's what sparked the question in the first place. –  loyalpenguin Feb 2 '12 at 18:38
4  
+1: Mix 2/3 with AOP and you have a wonderful way of using INPC. [Notifies]public int Foo { get; set; } –  Steve Evers Feb 2 '12 at 20:13
    
Why does not private setter guarantee immutability but the private variable does? –  Job Feb 3 '12 at 23:41
1  
@Job To any class accessing the class, a private setter is sufficient for immutability. However, inside the class, the private setter does not prevent repeated settings of the value, following initial construction. A language feature like a 'private readonly set' might conceptually work around this problem, but it does not exist. –  Sheldon Warkentin Feb 6 '12 at 20:16
1  
I'm new to C#, so tell me, why use public int Foo {get; set;} instead of public int Foo? –  user1827 Feb 27 '12 at 17:46
show 2 more comments

Generally, I would say assign to the field in the constructor and use the property everywhere else. This way, if someone adds functionality to the property, you won't miss it anywhere.

It certainly isn't a performance factor. The optimiser will inline a simple get or set for you and the final MSIL code will probably be identical.

share|improve this answer
    
Any particular reason for using the field in the constructor? Less chance of strange side effects? –  Sign Feb 2 '12 at 19:15
4  
@Sign: My guess is that if there is validation on the property (now or in the future), you don't want to run the risk of validation failing during construction. Validation isn't logical at this stage because the object can't be guaranteed to be stable until the constructor finishes. –  Steve Evers Feb 2 '12 at 20:10
    
@Sign: Both what you said and what Snorfus said. Or if I want to log changes to a property, I likely don't want to log the initial setting. But, I did say "generally". –  pdr Feb 2 '12 at 20:48
3  
@Sign: the problem is: if the set method of the property can be overridden in a subclass you can have a side effect during the creation of the object or an inconsistent object (i.e: the overridden property is programmed to not set any value for that field). Using properties in constructors is only safe if the set method is private or if the class is sealed. –  Diego Feb 3 '12 at 1:33
add comment

If there is any chance that those property get/set implementation will change sometimes later (for example, you want to rise an event when calling set, or you will add some lazy evaluation mechanism later to your get function), then it may be a good idea that your code inside the class will use the property in almost all cases except for the - most probably rare - cases where you explicitly don't want those event or lazy evaluation mechanisms to be used.

Anyhow, whatever you will do, there is a good chance that when you change the property implementation later in such a way, you will have to look at all places inside your class accessing those property to check if really the property shall be accessed or the private variable shall be used.

share|improve this answer
add comment

Depends.

First you should prefer automatic properties when possible:

public string MyValue {get;set;}

Second the better approach would probably be to use the properties, if you have any logic there you should probably be passing through it yourself, especially if that logic is thread synchronization.

But you should also take into account that it might hamper your performance (a little bit), if you are synchronizing incorrectly you can deadlock yourself, and sometime the correct path is to go around the logic in the property.

share|improve this answer
2  
I also like public string MyValue {get; private set;}. –  Job Feb 3 '12 at 23:43
add comment

Well, the straight-to-the-point approach would be to just assign it to the variable itself, since you're inside a class' method and you control the class' behaviour, anyway.

But the whole point about properties is that they abstract the variable away. Whereas such a simple property as in your example has completely no use over just a simple public member variable, properties usually do (or should do) additional things inside their getters and setters. And if you want these things done automatically when changing the property inside the class, then it is of course cleaner to work on the property instead of the variable to not have to change each variable assignment when the property setting behaviour changes.

You just have to reason about it conceptually. The property is actually a handle to access some internal state of the object, which may be comprised of more than one member variable. So you have to ask yourself if you want to change the underlying internal state only (or only part of it) or the abstract property representing this state at a whole, and most times it's indeed the latter since you usually want your object to always have a consistent state.

share|improve this answer
add comment

I always use the public property.

Often some logic which should always run when the property is set is added to the set method of a property, and setting the private field instead the public setter will bypasses any logic there.

You have a comment about MVVM leading to this question, and I feel this is even more important when working with MVVM. Many objects raise a PropertyChange notification the setter, and other objects can subscribe to this event to execute some action when specific properties change. If you set the private variable, these actions will never execute unless you also manually raise the PropertyChanged event.

share|improve this answer
    
+1 Yes in most cases (MVVM) the PropertyChanged event is a must. And that can only get fired inside a property. Good explanation. –  loyalpenguin Feb 2 '12 at 18:59
add comment

Generally, it's up to you what you should do with a property and its backing field when getting/setting.

Most often, just to be consistent across code, you should use public accessors wherever they are available and appropriate. That allows you to refactor with minimal code change; if the method doing this setting needs to be stripped out of the class and put somewhere else where the backing field is no longer available (like a base class), who cares? You're using something that's available wherever the class itself is to do the job. The backing field, in most cases, is an implementation detail; nobody outside your class should know it exists.

The main situation I can think of when you should use the backing field and NOT the property accessor is when the accessor has additional logic (validation, or updating other state information in the class) which you don't want to run. Initial population of an object is an example; you may have a class that uses two property values to calculate a third, which is also stored in a backing field (for persistence reasons). When initializing a new copy of that object given data from the DB, the property accessors which each recalculate the third value may complain if the other needed value is not set. By using the backing fields to set the initial values of these two (or three) properties, you bypass the validation/calculation logic until the instance is in a consistent enough state for the logic to work normally.

share|improve this answer
add comment

Always use the one that makes sense. Yes, I know that sounds pretty bogus to the point of being a non-answer.

The point of properties is to provide an interface through which you can safely access a data model. For most situations you always want to safely access the data model through that interface, such as:

public Foo Bar
{
  get { return _bar; }
  set { _bar = doSomethingTo(value); }
}

But in other situations, you may simply be using a property as a view of a data model:

public Double SomeAngleDegrees
{
  get { return SomeAngleRadians * 180 / PI; }
  set { SomeAngleRadians = value * PI / 180; }
}

If it makes sense to use the radians form of SomeAngle, then by all means use it.

In the end, be sure to drink your own kool-aid. Your public-facing api should be resilient enough to work internally.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.