5

I know in C# you can easily create accessors to a data type, for example, by doing the following:

public class DCCProbeData
{
    public float _linearActual { get; set; }
    public float _rotaryActual { get; set; }
}

However my colleague, advised me to do it this way:

public class DCCProbeData
{
    private float _linearActual = 0f;

    public float LinearActual
    {
        get { return _linearActual; }
        set { _linearActual = value; }
    }
    private float _rotaryActual = 0f;

    public float RotaryActual
    {
        get { return _rotaryActual; }
        set { _rotaryActual = value; }
    } 
}

My way seems simpler, and more concise. What are the differences and benefits of doing it either way?

Thanks

Edit Just a note, my colleague was able to generate the code for the "second way" using the Refactor option within the Class Details pane most easily found in a Diagram file. This makes it easy to add many Properties without having to manually create the accessors.

Ryan R
  • 8,342
  • 15
  • 84
  • 111
  • 1
    What benefits did your colleague mention when he advised you? – R. Martinho Fernandes Mar 24 '11 at 16:23
  • I'd think the explantaion was "your naming looks likle you are exposing internal variables publically. If you want to keep underscore versions for internal usage - make them private and provide public property with good name that wraps the _ fields." – Alexei Levenkov Mar 24 '11 at 16:27
  • @Martinho He mentioned something about the first one using anonymous objects but I was not very clear about what he meant. @Alexei Thanks, you are correct and I should use the naming convention of the properties like in the second way. – Ryan R Mar 24 '11 at 16:39
  • @Ryan: as you can see from the answers here, there are no "anonymous objects". When translating the short form to the long form, the compiler creates private fields with *unpronounceable names* (that is, there's no way you can use their names), so maybe that's what your colleague meant. – R. Martinho Fernandes Mar 24 '11 at 16:43
  • 4
    Don't forget to use 'prop' and then TAB TAB on the keyboard :-) – Ian Mar 24 '11 at 18:19
  • @Ian Nice! I never new about that. Is there a list of more of these? – Ryan R Mar 24 '11 at 18:36
  • I'm sure there is out there somewhere, have a Google. Some others I use are 'ctor' (constructor) and 'testm' (to create a test method, inside a Test Class) - again all proceeded with TAB TAB. I think there is one for foreach too. You can tell what keywords build code snippets like this I believe from looking at the intellisense - if you get 'prop' up in your intellisense list, for example, you will notice it has a weird shaped white box icon associated with it, as does ctor and testm, so that is probably the common sign of the code snippet keyword as far as I can gather. Enjoy :-) – Ian Mar 25 '11 at 07:49

13 Answers13

24

"Your way" just tells the compiler to create the second option. Unless you do something else in the getter or setter, they are functionally identical.

However, with "your way", I would recommend using the proper C# naming conventions. I would personally write this as:

public class DccProbeData
{
    public float LinearActual { get; set; }
    public float RotaryActual { get; set; }
}
Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • Just as extra info for the OP, you used to have to do it the long winded way but MS specifically introduced the shorthand because it was such a pain – Patrick Mar 24 '11 at 16:25
  • To add to this, the second method is often seen with code-generated classes or in places where custom logic is used within properties. My personal preference is the second method since it gives greater control over your class and is helpful when debugging. – Matt Bishop Mar 24 '11 at 16:27
  • 1
    For completeness, your colleague's way also allows for setting the default value of your properties. The numbers `0f` might be significant for something, in the context of your code. – T.K. Mar 24 '11 at 16:30
  • 1
    @Matt: how helpful is the second form when debugging, if there's nothing going on in that property? What will you debug in there? – R. Martinho Fernandes Mar 24 '11 at 16:30
  • @T.K.: 0f is the default value, so in this case, it's identical. You can, however, always set defaults in the constructor. @Martinho: My thoughts exactly - props show up in locals just as well as fields, too... – Reed Copsey Mar 24 '11 at 16:31
  • 1
    @Martinho : You're correct, simple accessors don't give you much, but what I'm referring to is placing breakpoints inside the getters and setters so you can see when your internal member is being hit and what its state is at various times. I like having a member I can hover over to see its internal state. This becomes especially helpful if an internal member is somehow transformed in a property and you want to compare the two. – Matt Bishop Mar 24 '11 at 16:38
  • @Reed : Depending on the default value of an integral type is a dangerous practice and initialization (when needed) is strongly recommended. – Matt Bishop Mar 24 '11 at 16:42
  • Thanks @Reed, so basically they are the same but I should fix my naming convention. My colleague also showed me how to automatically create the get/set, of the second approach, using the Refactor option within a diagram which is helpful. It seems that way a lot of code can be generated for me. Albeit, not as syntactically nice as the way I first did it. Thanks for all your help. – Ryan R Mar 24 '11 at 16:43
  • 2
    @Matt: ok, a breakpoint might come handy in some situations, but the frequency of that need wouldn't push me towards preferring the second. But it's a personal/team preference anyways. But why is depending on the specification (regarding default values) a dangerous practice? – R. Martinho Fernandes Mar 24 '11 at 16:43
  • @Martinho : I agree with you, and this is a bad place to bring it up since the needs are simple, but with more complex classes it can be nice to have. As to default values, C#'s compiler won't let you access an uninitialized type like `_linearActual` in the first place, the property just happens to get around the check. Somewhere in the class, whether it be the constructor or the definition, the member should be initialized. It's a perception thing really; "0" is not some magic default number to depend on, nor is something like int.MinValue "null" for an int like I see far too often. – Matt Bishop Mar 24 '11 at 18:14
  • 4
    @Matt: The spec **guarantees** that members fields are initialized to zeros if they're integral types, to false if they are bools, and to null if they are reference types. When there is no guaranteed initialization (like, uninitialized local variables) the compiler refuses to compile. So, yes *zero is a magic default number you can depend on*. You can consult sections §12.2 and §17.4.4 of the spec for details. – R. Martinho Fernandes Mar 24 '11 at 18:32
  • @Martinho : I'm not talking about any specs, I just refer to it as a dangerous practice. Using that mentality could lead to lazy patterns and unclear code. It doesn't hurt to set it to what you want, that way someone else can see that is the intent and it isn't ambiguous. This may be a preference but I feel it supports better coding standards. The "magic number" concept for anything should never be depended on. The slope becomes slippery if someone were to take this default value concept and infer nullability, maybe even checking values for 0! Types need "IsNull" flags when inside an object. – Matt Bishop Mar 24 '11 at 18:54
  • 1
    @Matt, There is no danger in assuming the defaults. The C# specs specifically call out what they are. As @Martinho stated, in the case of numerics it is 0, for booleans it is false, and in the case of reference types (including string) it is null. @Martinho even gave the relevent sections of the spec that spell this out. Also, it may cost you a little bit in performance as you are not initializing the value to zero, you are *re*initializing a value that was already zero. You may not care about that cost (and probably don't) but you should be aware of it. – Harry Steinhilber Mar 25 '11 at 12:24
  • @Harry : Let me repeat myself because I guess I'm not being clear. Never have I said that it's technically unsafe or would lead to runtime errors. The problem is that it's lazy and unclear coding to just expect defaults on something. If you want it that way, just set it. Think about who else might be reading your code and how easy or hard it might be to understand that. Also, I think both you and I know that performance costs on calling an integral type constructor are negligible. The rule is to always initialize before you read; be explicit and think about your community and clarity. – Matt Bishop Mar 25 '11 at 12:48
  • @Matt: Visual Studio used to give warning messages for performing unnecessary variable initializations in some circumstances. I think the warning was removed in 2010. See http://msdn.microsoft.com/en-us/library/ms182274(v=VS.90).aspx . Seems a pointless warning to me, since it's trivial for the compiler to optimize it out. So, it might lead to compiler warnings in some circumstances. – Brian Mar 25 '11 at 17:28
  • @Brian : That's interesting, and it's a rule that was put in place in 1.0 and effectively nullified when 2.0 came around and improved the compiler optimization from what I understand. – Matt Bishop Mar 25 '11 at 17:45
  • @Matt: True, but I don't think the warning itself was actually killed until VS2010. – Brian Mar 25 '11 at 18:00
3

The only difference is that you've named the fields.

(I'd stick with your colleagues naming convention for public properties though.)

kͩeͣmͮpͥ ͩ
  • 7,783
  • 26
  • 40
1

They do the same thing internally. The only difference is that you cannot directly access the backing field variable using Auto Implemented Properties.

Mike Cole
  • 14,474
  • 28
  • 114
  • 194
1

They are technically the same... the get/set is shorthand (auto property).

Lots of questions on SO about this:

  1. When to use get; set; in c#
  2. What is the { get; set; } syntax in C#?
  3. Auto-Implemented Properties c#
Community
  • 1
  • 1
Kelsey
  • 47,246
  • 16
  • 124
  • 162
1

Your way doesn't allow you to initialize the values, and your colleague's way follows a more-standard naming convention.

T.K.
  • 2,229
  • 5
  • 22
  • 26
1

I would like to add something that I haven't seen in the other answers, which makes #2 a better choice:

Using the first method you cannot set a breakpoint on the get and set.

Using the second method you can set a breakpoint on the get and set, which is very helpful for debugging anything accessing your private variable.

tbridge
  • 1,754
  • 1
  • 18
  • 35
1

Okay, the names have been mentioned before. It's also worth noting that as well as not being with the normal .NET conventions, beginning a public name with an underscore is not CLS-compliant (indeed, one reason for using it for private names is precisely because of this, it makes the distinction clearer, and should result in a warning with some code-checkers if you accidentally have the wrong access level).

Names aside, the one advantage to the latter form is that you can add more complicated code. Still, it's a non-breaking change to go from the former style to the latter, so there's no reason to do it before it's needed.

Jon Hanna
  • 110,372
  • 10
  • 146
  • 251
0

The first way is the way to go when you need simple properties with get and set and private storage done for you.

Use the second way if you need to do something special when you get or set the value.

Also, I recommend you stick to naming conventions using FxCop or ReSharper.

Winger
  • 676
  • 3
  • 7
0

I believe at the IL level, they both end up the same. In the background, VS creates autonamed variables for you when using the auto getters and setters.

Josh
  • 10,352
  • 12
  • 58
  • 109
0

The only way this could possibly be better is if you feel you will be adding more logic to the getters and setters at a later date.

Even then, this seems a little pointless.

Chris James
  • 11,571
  • 11
  • 61
  • 89
0

There is no difference, however prior to C# 3 you had to use the long way. At the end of the day it's a C# feature - syntactic sugar. They are both functionally identical.

R. Martinho Fernandes
  • 228,013
  • 71
  • 433
  • 510
m.edmondson
  • 30,382
  • 27
  • 123
  • 206
0

They are the same in the sense that your code sample will automatically generate backing fields.

But the two code samples are different because the names of the properties are not the same (LinearActual vs linearActual)

Greg
  • 23,155
  • 11
  • 57
  • 79
0

Things you can do when you don't use auto-implemented properties:

  • initialize to a default value
  • access or annotate the backing field (attributes)
  • read-only backing fields or immutability
  • set a breakpoint on access
  • have custom code around access to the variable
  • Use [System.ComponentModel.EditorBrowsableAttribute()] to enable custom logic on the accessors that you avoid accidently bypassing while coding
    • hides the backing field from intellisense

Conversion between the two ways is made very simple with ReSharper.

This is not to say don't use them by all means use them, unless you have a need for any of the other functionality listed.

Maslow
  • 18,464
  • 20
  • 106
  • 193