Setting property or field when inside of class?

3.1k views Asked by At

Well I am learning properties and I am not sure about the following:

class X
{
  private int y;

  public X(int number)
  {
    this.Y=number; // assign to property
    OR
   this.y=number //?
  }

  public int Y;
  {
    get; set;  
  }

}
7

There are 7 answers

0
alexl On

When you use autoproperties like:

  public int Y;
  {
    get; set;  
  }

You don"t need a private property because it's autogenerated. so you class will be:

class X
{   
  public X(int number)
  {
    Y = number;
  }

  public int Y // no semicolon here, comment added for edit length
  {
    get; set;  
  }
}

Hope this helps

5
user On

When you use auto-properties (get; set; or a variant thereof), the backing variable is not accessible. Those can, for the most part, be treated as simple variables, especially internally.

If you need to perform custom validation or mutation logic in the mutator, or otherwise have the need for an explicit backing variable, you cannot use auto-properties but have to write stub get and set methods yourself.

0
Marc Gravell On

They do different things; I would do Y = number; and remove the (unused) field y. In an automatically implemented property, the compiler creates it's own field (with a horrible name that you can't see in C#) - you don't need to provide your own field. So:

class X
{
  public X(int y)
  {
    Y = y;
  }
  public int Y { get; set; }    
}

Other points: changed number to y to be clearer to the caller, and also you don't need this. since it isn't ambiguous (field vs parameter, etc).

0
oleveau On

You have two choices :

class X
{
    private int y;

    public int Y
    {
        get { return y; }
        set { y = value; }
    }

    public X(int number)
    {
        Y = number;
        //equivalent to 
        y = number;
        // but you should use the public property setter instead of the private field
    }
}

or with auto-properties , it's even simpler :

class X
{
    private int y;

    public int Y
    {
        get; set;
    }

    public X(int number)
    {
        Y = number;
    }
}
0
Emond On

When not using auto-properties I always use the Property setter because there can or will be code in the setter that I need to be executed. This code could be a domain check or the raising of an event such as PropertyChanged.

0
explorer On

Only assign to a field (private int y) inside the property representing that field (public int Y {get;set}). No where else in the class should the backing field be assigned to directly. Always do it through the property... yes even in the constructor. It follows from the do not repeat yourself (DRY) principle.

This is recommended because whenever in future you want to associate some behavior to be triggered by that assignment you only have a single place (the set accessor) to write code into.... not all the places where the field is assigned to !!

   class X   
   {   
    private int y; //not strictly necessary but good for documentation

    public X(int number)
    {
        Y = number;
    }

    public int Y { get; set; }


    }
0
Radu094 On

A point I usually try to make about accessing backing variables:

Sometimes the public getter might contain complicated data validation,raising property changed events or some other complex code that is triggered when some external code changes it's value.

When changing that value internally (from inside the class), it might be a valid point to use the backing variable directly if your intention is to skip all the validation and events from the public setter. It's like saying "i'm the class instance, I know what I'm doing". This way the public setter is acting like a guard-dog, sanitizing external input, while I can still set the property internally to whatever I need.

class X   
   {   
     private int y; //not strictly necessary but good for documentation

    public X(int number)
    {
        y = GetYValueFromDB();  //we assume the value from DB is already valid

    }

    public int Y { 
       get{ return y}; 
       set { 
       if (ComplexValidation(value)
         {
           RaiseOnYPropertyChanged();
           y = value;
         }
        }


    }