33
votes

I understand the advantages of PROPERTIES over FIELDS, but I feel as though using AUTO-implemented properties over MANUAL implemented properties doesn't really provide any advantage other than making the code a little more concise to look at it.

I feel much more comfortable using:

    private string _postalCode;

    public string PostalCode
    {
        get { return _postalCode; }
        set { _postalCode = value; }
    }

Instead of:

public string PostalCode { get; set; }

primarily because if I ever want to do any kind of custom implementation of get and set, I have to create my own property anyway backed by a private field. So why not just bite the bullet from the start and give all properties this flexibility straight away, for consistency? This really doesn't take but an extra second, considering that all you have to do in Visual Studio is click your private field name, and hit Ctrl+E, and you're done. And if I do it manually, then I end up with inconsistency in which there are SOME manually created public properties backed by private fields, and SOME auto-implemented properties. I feel much better with it being consistent all around, either all auto or all manual.

Is this just me? Am I missing something? Am I mistaken about something? Am I placing too much emphasis on consistency? I can always find legitimate discussions about C# features, and there are almost always pros and cons to everything, but in this case, I really couldn't find anyone who recommended against using auto-implemented properties.

7
You're saying you may as well do it now - because in the future you might have to. Why waste time doing something which is prone to error (you will probably end up copying & pasting anyway), when you can do it only when needed?Rob♦
Thanks Rob. My reasoning is that with Visual Studio, I can create manually implemented properties with just one extra key press, so there is no copy/pasting. And if someday I do need to create my own implementation, I don't end up with a rift between auto-implemented properties and manually implemented properties, it's 100% one or 100% the other. By just going full on manual from the start, I can create my own implementation at any time without having some properties be auto-implemented, and some properties be manual. I see your point though, definitely.CptSupermrkt
In that case, I'm with you in sticking with 100% manual implementation.. I tend to have a bias after having run into many typo'd bugs with manual getters / settersRob♦
in VS 2010 (at least), you can type prop and press tab. This results in an auto-implemented property.cwharris

7 Answers

38
votes

It doesn't grant you anything extra beyond being concise. If you prefer the more verbose syntax, then by all means, use that.

One advantage to using auto props is that it can potentially save you from making a silly coding mistake such as accidentally assigning the wrong private variable to a property. Trust me, I've done it before!

Your point about auto props not being very flexible is a good one. The only flexibility you have is by either using private get or private set to limit scope. If your getters or setters have any complexity to them then the auto props are no longer a viable option.

10
votes

Auto-implemented properties are not guaranteed to keep the same backing field name between builds. Therefore, it is theoretically possible that serializing an object in one version of an assembly, and then re-serializing that same object in another assembly could cause breaking changes.

This is highly unlikely, but it is a valid concern if you're trying to maintain the ability to "swap out" version of your assemblies for newer versions.

By using manually implemented properties, you're guaranteed that the backing field never changes (unless you change it specifically).

Aside from that minute difference, an auto-property is a normal property that is implemented automatically with a backing field.

2
votes

There are people who think that automatic properties can be somewhat evil but apart from that they are just syntactic sugar. You don't gain anything by using them apart from saving a few lines of code and you can potentially create more work for yourself (by having to implement it manually anyway later on because you want to do some checking or raise an event). Consistency is quite valuable in programing (imho).

2
votes

One of the things that you will lose control over is the ability to specify the backing field as NonSerialized, but it is easy enough to create a backing field for the property in this case.

Forgot: if you or any product that you use performs reflection on the members (i.e. WCF), then you will see the mangled backing field name instead of a "pretty" backing field that you created.

This could be very important if you had previously provided access to the service or if you deserialize on the receiving end into the same class structure (i.e. the same classes are used on both ends of the WCF pipe). In this case, you would not necessarily be able to deserialize because you could guarantee that the backing field name is the same unless you share the same DLL as opposed to the source code.

A little more clarification: assume that you have a web service that exposes some of your business objects over WCF to a silverlight client that you have created. In order to reuse your business logic, your Silverlight client adds references to the source code for your business objects. If you have auto-implemented properties, you have no control over the backing field name. Since WCF serializes the members and not the properties, you cannot be sure that the object transferred to silverlight from the WCF service will deserialize correctly because the backing field names will almost certainly be mismatched.

2
votes

I don't know about everybody else, but I tend to pause a moment to think what I should name my variables and functions so others can understand my code.

So when I use auto-implemented properties, I only have to pause once.

When I need a backing field I have to pause two times, so it slows down development a bit :)

The way I do it is:

  1. Make it a private variable in the start
  2. Change it public auto-implemented if needed.
  3. Change it to backing field if I need some code in get or set.

There is nothing wrong if different properties of a class are exposed differently.

1
votes

One of the advantage I see using auto properties is; while debugging the application it won't step into unnecessary Get/Set section. I know that we can avoid same using Debugger Attributes or Step over; however it happen most case if be do debug on a large application.

0
votes

I can always find legitimate discussions about C# features, and there are almost always pros and cons to everything, but in this case, I really couldn't find anyone who recommended against using auto-implemented properties.

I came across this question during a code review today, and when I asked around my peer group, we could not come to a consensus either. I dislike ambiguity, and I wanted to know at least one burning question that would answer you question:

  • Is there a performance gain or hit using one way over another?

Like finding out how many licks it takes to get to the center of a Tootsie Roll Tootsie Pop, I decided "lets find out".

Lets first actually do an apples to apples comparison.

Suppose we have two classes:

public class C 
{
    private int z;
    public int Z
    {
        get { return z;}
    }
}

public class Q
{
    public int Z { get; }
}

The first class is a manual backing store, the second the auto compiler generated version.

Lets take a look at the IL generated for each.

First, the manual backing store version:

// Fields
.field private int32 z

// Methods
.method public hidebysig specialname 
    instance int32 get_Z () cil managed 
{
    // Method begins at RVA 0x2050
    // Code size 12 (0xc)
    .maxstack 1
    .locals init (
        [0] int32
    )

    IL_0000: nop
    IL_0001: ldarg.0
    IL_0002: ldfld int32 C::z
    IL_0007: stloc.0
    IL_0008: br.s IL_000a

    IL_000a: ldloc.0
    IL_000b: ret
} // end of method C::get_Z

.method public hidebysig specialname rtspecialname 
    instance void .ctor () cil managed 
{
    // Method begins at RVA 0x2068
    // Code size 8 (0x8)
    .maxstack 8

    IL_0000: ldarg.0
    IL_0001: call instance void [System.Private.CoreLib]System.Object::.ctor()
    IL_0006: nop
    IL_0007: ret
} // end of method C::.ctor

// Properties
.property instance int32 Z()
{
    .get instance int32 C::get_Z()
}

Now lets look at the IL for the second class:

// Fields
.field private initonly int32 '<Z>k__BackingField'
.custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
    01 00 00 00
)
.custom instance void [System.Private.CoreLib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [System.Private.CoreLib]System.Diagnostics.DebuggerBrowsableState) = (
    01 00 00 00 00 00 00 00
)

// Methods
.method public hidebysig specialname 
    instance int32 get_Z () cil managed 
{
    .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
        01 00 00 00
    )
    // Method begins at RVA 0x2071
    // Code size 7 (0x7)
    .maxstack 8

    IL_0000: ldarg.0
    IL_0001: ldfld int32 Q::'<Z>k__BackingField'
    IL_0006: ret
} // end of method Q::get_Z

.method public hidebysig specialname rtspecialname 
    instance void .ctor () cil managed 
{
    // Method begins at RVA 0x2068
    // Code size 8 (0x8)
    .maxstack 8

    IL_0000: ldarg.0
    IL_0001: call instance void [System.Private.CoreLib]System.Object::.ctor()
    IL_0006: nop
    IL_0007: ret
} // end of method Q::.ctor

// Properties
.property instance int32 Z()
{
    .get instance int32 Q::get_Z()
}

Ignoring the extra compiler generated code for adding debuggable attributes, which add no appreciable executable code, there does not appear to be any difference in the generated code.

Now, you might argue that your question is not answered, but consider...

If you have ever coded properties that participate in binding, such as:

    private string name;
    public string Name 
    { 
        get { return name; }
        set { SetProperty (ref name, value);
    }

Then the backing store is the way to go.

On the other hand, using the "prop" <TAB><TAB> shortcut in the Visual Studio editor to generate the auto properties is just super handy, and is much faster than all that typing ;)

So in the end, to the hammer, everything looks like a nail. Don't be a hammer.