1

I've been going through examples for properties compared to fields, and one thing I always see without explanation is the creation of a private field, and then a property. Why do we need _foo, and can't just run the code similar to what I have below, or maybe replace Foo = Foo with Foo = value?

I saw it created a stack overflow exception when I ran it, so I guess it's looking for a value to fill Foo or value with, but I would think that would be handled when I do def.Foo = 55.

Even if it is best practice to create the private field, I'd still like to get a better understanding of what's actually causing the overflow.

class ABC
{
    private int _foo; //Why create this?
    public int Foo
    {
        get { return Foo; }
        set
        {
            Foo = Foo;//more logic would go here. }
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        ABC def = new ABC();
        def.Foo = 55;
        Console.WriteLine($"The value of Foo is {def.Foo}.");
        Console.ReadLine();
    }
}
1
  • your get and set should return _foo, not Foo... and set _foo not Foo. Otherwise it's infinite, and therefore the overflow Commented Feb 23, 2016 at 5:51

3 Answers 3

3

That is because field and property are not the same.

private int _foo; //field
public int Foo //property
{
    get { return _foo; } //should be _foo
    set
    {
        _foo = value;
    }
}

Typically, you use public property to access private field because you might want to do something else other than the assigning/getting the value of the field.

Example:

private bool selectedIndexChanged; //note this additional field
public bool SelectedIndexChanged {
    get { return selectedIndexChanged; }
    set { selectedIndexChanged = value; }
}

private int selectedIndex; //Why create this?
public int SelectedIndex
{
    get { return selectedIndex; }
    set
    {
        selectedIndexChanged = value != selectedIndex; //you update selectedIndexChanged here!
        selectedIndex = value;
    }
}

Note that you don't directly access the private fields, but you access them through public properties. And the good thing about having properties is that you not only able to read/assign the field value, but you also can do something else: checking the validity of the inputs, assigning some other fields, call event, etc...

Even if it is best practice to create the private field, I'd still like to get a better understanding of what's actually causing the overflow.

The overflow is not caused by the best practice but by the wrong practice:

private int _foo; //Why create this?
public int Foo
{
    get { return Foo; } //this should not happen, wrong practice
    set
    {
        Foo = Foo; //neither should this happen, another wrong practice
    }
}

What happen in the code above is:

  1. You get Foo, which return Foo which you need to get Foo, which you need to get Foo, which return Foo which you need to get Foo return Foo, which you need to get Foo, which return Foo which you need to get Foo return Foo, which you need to get Foo, which return Foo which you need to get Foo return Foo, which you need to get Foo, which return Foo which you need to get Foo return Foo, which you need to get Foo, which return Foo which you need to get Foo return Foo, which you need to get Foo, which return Foo which you need to get Foo return Foo, which you need to get Foo, which return Foo which you need to get Foo return Foo, which you need to get Foo, which return Foo which you need to get Foo return Foo, which you need to get Foo, which return Foo which you need to get Foo return Foo, which you need to get Foo, which return Foo which you need to get Foo return Foo, which you need to get Foo... till infinity

And likewise:

  1. You set Foo, need to get Foo which return Foo which you need to get Foo, which you need to get Foo, which return Foo which you need to get Foo return Foo, which you need to get Foo, which return Foo which you need to get Foo return Foo, which you need to get Foo, which return Foo which you need to get Foo return Foo, which you need to get Foo, which return Foo which you need to get Foo return Foo, which you need to get Foo, which return Foo which you need to get Foo return Foo, which you need to get Foo, which return Foo which you need to get Foo return Foo, which you need to get Foo, which return Foo which you need to get Foo return Foo, which you need to get Foo, which return Foo which you need to get Foo return Foo, which you need to get Foo, which return Foo which you need to get Foo return Foo, which you need to get Foo, which return Foo which you need to get Foo return Foo, which you need to get Foo... till infinity

Thus causing overflow...

Sign up to request clarification or add additional context in comments.

Comments

1

Properties are actually get/set methods for actual variables. But you don't always need to have private variable to have a property.

You can simply have

public int Foo { get; set; }

Compiler will do the magic of creating and setting variables for you. But variables for properties are needed in case you need to restrict property from getting assigned wrong values or do some additional tasks.

Example:

private int _score;
public int Score
{
    get { return _score; }
    set
    {
        if(value > 100)
            throw new Exception("Score cannot be more than 100");

        _score = value;
    }
}

Comments

1

Why do we need _foo, and can't just run the code similar to what I have below, or maybe replace ?

Because properties are methods that either set or get the value of a field. So, you have to have defined a field first. This is required if you have to imply any logic inside especially in the setter. Otherwise, it is more common to use an auto-implemented property.

Even in the case, where we use a auto-implemented property, the compiler generates for us a backing field.

public Person
{
    public string FirstName { get; set; }
}

For instance, doing this

var person = new Person { FirstName = "Bob" };

You create a new Person object, with a property called FirstName, whose type is string. Furthermore, you set the value of person's FirstName to Bob. Here is the point you have to pay attention. The compiler would have generated a backing field of type string and at runtime this would be the place, where a reference to the person's firstname would be stored.

The above class's definition is similar to the following one:

public Person
{
    private string _firstName;
    public string FirstName
    {
        get { return _firstName; }
        set { _firstName = value; }
    }
}

This is actually, what does the compiler behind the scenes, when you define auto implementd properties. Based on this, we can say that a reference to the string "Bob" would be stored to the _firstName.

1 Comment

Except that properties don't have to access any field at all. Consider DateTime.Now.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.