4

With Unity5 (it's hard to know exactly what version of c#/Mono/.Net is being used), we do properties exactly like this:

private int _distance;
public int Distance
    {
    private set
        {
        _distance = value;
        controls.Blahblah(_distance);
        }
    get
        {
        Debug.Log("hah!);
        return _distance;
        }
    }

But consider the new "automatic properties" in c#, which seem to be like

 public int Distance {get; set;}   // ?

but I don't know how to "do something" in the getter/setter ??

Or in other words, is there a way to auto generate the backing variable (as well as the convenience -- to keep it private) when "manually" making a Property?

To repeat since this was marked as a duplicate, how can I "do stuff" in the automatic Property idiom during the getter/setter ...

... or conversely ...

how to hide, get rid of, or automatically supply the backer if you write your own "manual" properties?

Note that of course you or another programmer can accidentally touch the _underscore backing variable: is there any way at all to avoid that??

Fattie
  • 27,874
  • 70
  • 431
  • 719
  • 1
    You're doing it right if you have to add more code. Auto properties can't have additional code in them, it's just shorthand. – Blue Eyed Behemoth Feb 23 '16 at 15:07
  • 2
    "Auto properties" are just syntactic sugar for exactly what you're doing with an explicit backing field, so it's fine. (The big difference with auto properties is that the backing field is hidden from you, and you can't write any code to react to the properties being read or written.) – Matthew Watson Feb 23 '16 at 15:11
  • 1
    this question has nothing to do with unity, should remove the tag – sara Feb 23 '16 at 15:16
  • Hi Kai: actually it does, very much so. I'm not sure if you use Unity, but, it's always an endless challenge trying to find out *just what* flavour of language / compiler / Mono is actually available in Unity. For example I have no clue if c#6 features are available at this moment in Unity. I appreciate that ***in this case*** (if I understand correctly) the answer applies to all c# as of now - but "Unity c#" is specific. (Indeed you could say it's Unity5 question - indeed as I tagged it.) – Fattie Feb 23 '16 at 15:21
  • @BlueEyedBehemoth and others ... *"it's just shorthand"* ... it occurs to me the autoproperties are actually ***more than shorthand*** - the one advantage is, you do indeed avoid having ***an exposed backing variable***. – Fattie Feb 23 '16 at 15:22
  • 1
    then I stand corrected :) – sara Feb 23 '16 at 15:23
  • 1
    @JoeBlow You're right, it does do a lot on the compiler side. – Blue Eyed Behemoth Feb 23 '16 at 15:28
  • 1
    I wish we could have access to private field "generated", and to create partialy automated properties like only get or set:/ – Jerry Switalski Feb 23 '16 at 15:43
  • @JoeBlow I was refering to my imagination now not to CLR doco :D – Jerry Switalski Feb 23 '16 at 15:45
  • Possible duplicate of [C# automatic property](http://stackoverflow.com/questions/1735235/c-sharp-automatic-property) – MotoSV Feb 23 '16 at 17:58
  • Hi Moto dude - as you know I close almost every unity question :) I clarified the question, cheers. Note that the many informative answers here, the info is not given in the suggested dupe. – Fattie Feb 23 '16 at 18:04
  • "c# rather than unity" see above "Hi Kai (now Moto): actually it does, very much so. I'm not sure if you use Unity, but, it's always an endless challenge trying to find out just what flavour of language / compiler / Mono is actually available in Unity. For example I have no clue if c#6 features are available at this moment in Unity. I appreciate that in this case (if I understand correctly) the answer applies to all c# as of now - but "Unity c#" is specific. (Indeed you could say it's Unity5 question - indeed as I tagged it.) " – Fattie Feb 23 '16 at 18:07

4 Answers4

3

You can't use auto-properties if you want to "do something" in the getter/setter, apart from just assigning to the field. For the use-case described by your example code, auto-properties are not an option. There is nothing wrong with having an explicit backing field.

sara
  • 3,521
  • 14
  • 34
  • Ahh .. beautiful explanation, thank you Kai. Can you clarify: regarding the backing variable: ***is there a way to 'get rid of' the backing variable*** in my example case? (There are many problems with such backing variables: imagine for example if it was accidentally touched elsewhere.) In any event, these days ***is there a way to 'get rid of' the backing variable*** in my example case? Thanks! – Fattie Feb 23 '16 at 15:16
  • 1
    nope, you're stuck with it. you can mitigate risk by having conventions about only manipulating fields via well-defined methods/property accessing. this is normally enforced by making sure everyone on the team knows the "rules" and doing code reviews. – sara Feb 23 '16 at 15:18
  • Interesting to hear that confirmed! You rock, Kai. – Fattie Feb 23 '16 at 15:19
  • Is there any reason to use automatic properties instead of fields? Reflection and code unification are the only reasons I see but they are not good enough for me. I have a habit to use public fields instead of public automatic properties as for security reasons it is the same solution. – Jerry Switalski Feb 23 '16 at 15:53
  • One (not very convincing) argument is that "it's easier to extend in the future", but your IDE can take care of that for you. Another one is debugging breakpoints. I think the best one is being able to specify a public getter with a private setter though. I think auto-properties with public setters are an anti-pattern and should be avoided as religiously as public fields themselves. – sara Feb 23 '16 at 15:59
  • @kai are you saying that you can put breakpoint for debugger on setter or getter? And agreed that specifing scope makes big sence for using this .NET feature. – Jerry Switalski Feb 23 '16 at 16:10
  • @JerrySwitalski yes, since property getters/setters are actually methods, you can break on them in a debugger which can be helpful in some circumstances. I think it's a pretty weak argument though. the debugger should be used as a tool to deal with already existing bad code that you need to understand, not as an excuse to write new code that is hard to understand without a debugger. – sara Feb 23 '16 at 16:21
  • @kai I said this wrong. I know we can put breakpoint in getter or setter, but my question is can we do it on automatic properties as there is no body of setter or getter. You stated that this is one of the uses of automatic properties that makes sense for them. – Jerry Switalski Feb 23 '16 at 16:34
  • Hi @JerrySwitalski by "fields" do you mean normal variables or something else? Properties are incredibly useful in many basic ways .. (it's rather like KVO, you could say) it's an absolute basic necessity, yeah. – Fattie Feb 23 '16 at 18:05
  • hi @JerrySwitalski if you mean is there any use for the ***automatic*** ones - they seem totally useless to me, other than that, they are beautiful placeholders for when you later write getters/setters. – Fattie Feb 23 '16 at 18:06
  • @JoeBlow yeah fields are just without getters and setters. I see your point. – Jerry Switalski Feb 23 '16 at 19:15
3

If you have only the private variable without any other logic then you can use Auto properties.

Class Something something
{
    public int Distance
    {
    private set
     {
       _distance = value;
     }
    get
     {
       return _distance;
     }
    }

// Keep this at the end of the class
// In visual studio you can collapse region and wont attract
// attention/distracting in your editor.

#region data members
private int _distance;
#endregion data members
}

you can replace it with public int Distance {get; set;}

But if you do other actions like logging, then you have to write it in traditional way.

Edit

Its all coding practice. I generally enclose the private variables in a #region p ...#endregion. And use only the Properties for setting - Distance and have never used _distance. Its more of a coding practice than an actual fix for what you are doing.

One more reason I do that is - In WPF we would need to call NotifyPropertyChanged event whenever we set the properties. It will be a bug if I don't use the property name. So this habit of using Properties over private variables stuck.

You cannot make the variable un-discoverable, just grouping them together for easy readability and Yes this is human enforced practice.

Carbine
  • 7,849
  • 4
  • 30
  • 54
  • Find in files... `._`. Shouldn't give you any hits, unless you were to do `object._variable` somewhere... – Pimgd Feb 23 '16 at 15:27
  • hey sorry for confusion. It will still be available through out the class – Carbine Feb 23 '16 at 15:31
  • You can collapse regions in visual studio editor. so that unwanted clutter will be hidden when you read code. – Carbine Feb 23 '16 at 15:31
  • 1
    [#region wasn't meant to be (ab)used like this](http://programmers.stackexchange.com/a/53114/68834) – Mathieu Guindon Feb 23 '16 at 15:37
  • @Mat'sMug incidentally I have read this earlier. Although the post has valid points on refactoring. Its perfectly reasonable for me to use regions for hiding the boilerplate code which clutter the code. Its subjective but I am biased towards using regions for such cases. In the above scenario you need to have a private variable which is un-avoidable and its a clutter. – Carbine Feb 23 '16 at 15:41
  • what is WPF ?? @CarbineCoder dudester – Fattie Feb 23 '16 at 19:52
  • @JoeBlow the post I linked to actually covers pretty much every single possible usage of `#region`, not just *inside a method*. BTW, WPF stands for *Windows Presentation Foundation*, the UI framework for Windows desktop application development, that replaces (well, wants to) the old Windows Forms. – Mathieu Guindon Feb 23 '16 at 19:56
2

Automatic properties do not allow you to do 'anything' in them. They are simply shorthand for:

public int Distance
{
    get
    {
        return _distance;
    }
    set
    {
        _distance = value;
    }
}
private int _distance = default(int);

There is nothing wrong with using an actual variable in this property, it will not affect anything.

One thing to keep in mind though, is if you want to edit a variable in the editor, you cannot use a property. You will need to expose a public field:

public int Distance;
Mathieu Guindon
  • 69,817
  • 8
  • 107
  • 235
rhughes
  • 9,257
  • 11
  • 59
  • 87
  • Quite, an excellent point about inspector variables. (A handy quick solution in such cases -- say during development you want to set a Property from the Inspector .. we just use another ordinary inspector variable, and then use `void OnValidate()` to set the Property in question from it. This is extremely handy. – Fattie Feb 23 '16 at 15:19
  • 1
    or you could expose the private field via `[SerializeField]` – benscabbia Jun 08 '17 at 20:27
1

If your get and set needs to have extra code like you have for logging, you have to implement them the way you did it first way, if you just need to get and set the value then auto implemented properties are better i mean the 2nd approach.

Ehsan Sajjad
  • 61,834
  • 16
  • 105
  • 160