16

Possible Duplicate:
c#: why have empty get set properties instead of using a public member variable?

string name;

vs

string name {get; set;}

Assuming your get and set are blank as above, what's the point in specifying them?

Community
  • 1
  • 1
NibblyPig
  • 51,118
  • 72
  • 200
  • 356

8 Answers8

24

It encapsulates the compiler generated field, and provides you, the class or struct developer the ability to update it internally later without breaking your API by simply modifying the get/set part that you care about.

For instance, suddenly never want to return null? You can do that by simply changing the empty get to get { return storedName ?? ""; }. Of course, it means you suddenly need to manually control the variable, but that's a small price to pay for the flexibility.


The first use is an example of a field declaration. The second use is an example of an auto-implemented property.

It is generally bad practice to provide direct access to a field. However, the .NET team noticed that a lot of getters/setters are basically just that. For example, consider the following:

// C#
public string Name
{
    get { return name; }
    set { name = value; }
}

// Without properties (or a Java implementation)
public void setName(String name)
{
    this.name = name;
}

public String getName()
{
    return name;
}

Either way, that's a lot verbosity to really just expose a field. However, it is regularly the case that, as a developer, you need to go back and change how a field is handled internally, but you do not want to break or even affect other code if you can get away with it.

That is why using direct access to fields is bad. If you provide direct access to fields, but need to change something about using the field, then all code that uses that field must change as well. If you use a property (or even a method), then you can change the internal code and potentially not effect external code.

Consider the following example:

public string Name
{
    get;
    set;
}

Later you decide that you need to raise a changing and changed event around the setter. If you exposed a field, then it's time for a potentially big rewrite. If you used properties (or a method), then you can just add the logic there. You suddenly lose the benefit of auto-implementing properties, but you gained the ability to refactor your class without breaking existing code.

private string name;
public event NameChangingEventHandler NameChanging;
public event NameChangedEventHandler NameChanged;

public string Name
{
    get { return name; }
    set
    {
        OnNameChanging(/*...*/);
        name = value;
        OnNameChanged(/*...*/);
    }
}

protected virtual void OnNameChanging(/*...*/) { }
protected virtual void OnNameChanged(/*...*/) { }

All of that maintains your public API and requires no work from users of the class (the rest of your code, or external developers using of your API). Breaking changes are not always avoidable, but avoiding direct access to fields is a good step to try to ensure that it won't happen. Auto-implemented properties are a quick, and easy way to do it.

(Unrelated: lost power while typing this and I am very happy that my browser saved most of it!)

pickypg
  • 22,034
  • 5
  • 72
  • 84
  • 1
    Good answer; you'll get my +1 if you mention the difference between properties and fields. – Justin Morgan - On strike May 24 '11 at 16:21
  • 2
    That sorta makes sense, but if you have `string name;` and later you decide 'pants, i want to restrict the set; to not null', you can just change it to string name {get; set { .. } } surely? Other code will be doing myObject.name and won't notice the difference... – NibblyPig May 24 '11 at 18:03
  • 4
    @SLC: Other code will notice the difference. Under the hood, `string name;` declares a location within the object where a pointer to a string is stored. `string name {get; set;}` declares a set of procedures that can be used to ask the object for a string, or tell the object to store it (the location where this string is stored is automatically generated by the compiler). Since they're so different, the actual instructions for working with them are different - and so if you change from one to then other code will break unless you recompile it. – Sean U May 24 '11 at 18:12
  • Will adding an empty accessor direct to the lowercase, private version of the value or to the public one? – kettlepot Feb 03 '12 at 21:37
  • @GabrieleCirulli Can you give an example of what you are saying? In C#, if you specify `name = "some value";`, then it will use the private variable (assuming you have access to it) and `Name = "some value";` will always use the property because C# is case sensitive. – pickypg Feb 06 '12 at 18:53
  • Say I define `private string name;` and `public string Name { get; set; }`. Will `name` be used as the backing store for `Name` or will an inaccessible backing store be created in this case too? – kettlepot Feb 06 '12 at 20:57
  • @GabrieleCirulli No, the backing field will be auto-generated by the compiler, and it cannot be referenced by your code. The only reason to make the field and the property is to use the field in the property (and possibly in other functions). If you can get away with a simple get-set implementation, then simply forgo creating the backing field and save yourself some code. – pickypg Feb 07 '12 at 23:49
  • What would break by changing `string name;` to `string name {get; set;}` when you need the extra functionality? (I just noticed that Sean U sort of answered this, so am I to understand that nothing would actually break so long as you recompile? Or is there more to it?) – Kyle Delaney Sep 15 '16 at 02:56
  • Any code that is already compiled that depends on the former code will not work against your change. It's looking for a field, not a parameter. – pickypg Sep 15 '16 at 03:01
1

The first one is actually a Field, but the second one is an Auto-Implemented property. The difference between them has already been discussed.

Community
  • 1
  • 1
Alireza Maddah
  • 5,718
  • 2
  • 21
  • 25
1

The first, assuming it's declared in class scope, is a field name. It's accessed as a field. The second is a property. A Blank get/set is known as an auto-property.

Stealth Rabbi
  • 10,156
  • 22
  • 100
  • 176
1

You might need to actually do something in your accessors in the future. Changing a field (which is what your first declaration is) to a property is a breaking change, so specifying accessors in advance is a small investment in the future.

Rik
  • 28,507
  • 14
  • 48
  • 67
1

Being able to add logic to a field's accessors without breaking compatibility is the standard explanation, and it's certainly a big one if you're writing a library or an application that's split among several assemblies that might be updated independently. I think it's something that one could dismiss as less of a concern if you're working on any sort of "all-in-one" software, though, since it'll all be recompiled anyway.

But even then, there's still another very compelling reason to only expose properties in your public interfaces: Even if you never need to make any internal updates, using fields can still lead to other problems on down the line because many portions of the .NET framework strongly prefer properties to fields. WPF, for example, does not generally support binding to fields. You can get around that by doing fancy things like implementing ICustomTypeDescriptor, but it's just so much easier to simply type {get; set;}.

Sean U
  • 6,730
  • 1
  • 24
  • 43
0
string name {get; set;}

This is called auto implemented property. Actually, C# creates variable starting with _ itself, so on get, that variable value is fetched and on set, that variable value is set. Its just like normal properties. Where as string name; is just a field.

FIre Panda
  • 6,537
  • 2
  • 25
  • 38
0

The first is a variable, the second is a (shorthanded) property

cusimar9
  • 5,185
  • 4
  • 24
  • 30
  • 1
    They're both variables. The first one is a field. – Justin Morgan - On strike May 24 '11 at 16:19
  • Justin, no, cusimar9 is basically correct. The OP just put "string name" without any context. It could have easilly been a class field or a method variable. The question isn't specific. – Stealth Rabbi May 24 '11 at 16:23
  • 4
    @Justin: a property is not a *variable* in C#, even if it has a setter. A variable is defined as a *storage location*. A property is not a storage location, rather, a property is simply a pair of methods, one called the getter and one called the setter. That the setter often changes the value of a variable does not make the property a variable. You cannot use a property in any context that *requires* a variable; for example, you cannot pass a property as an "out" or "ref" argument; those require variables. – Eric Lippert May 24 '11 at 16:25
  • @Eric - That makes perfect sense. I guess I use properties in variable-like ways so often that I tend to think of them that way, but it's really just the syntactic sugar of the language making them *look* like variables. – Justin Morgan - On strike May 24 '11 at 16:40
  • By the way, the downvote wasn't from me. Adding an upvote now because this is correct. – Justin Morgan - On strike May 24 '11 at 16:42
0

Properties are very nice, but as a general rule, objects shouldn't expose state to the public; they should be a black box from the perspective of outsiders. And you especially shouldn't state to direct change. State should change as a side effect of asking the object instance to do something useful in the problem domain.

If you are going to expose state, expose it as a read-only property (e.g. public widget Foo { get ; private set ; }).

Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135