2

I am learning about c# and I am a little confused about (non-automatic)properties and the local variable that the property uses.

When I use properties, I put an underscore for all the private variables that is used by properties. This helps me differentiate between regular private variables and private variables used by properties. By being able to differentiate, I would quickly know if I should use the property or the underlying variable to change/set the value.

However, I recently saw that using underscore and Hungarian notation is a not so good thing. But without the notation I might accidentally call the private variable instead of the property and the logic in the property might not get called (creating bugs because the property might throw an event, or throw an exception, or check the value, or change returning variable depending on the state of the class).

What are the alternatives to this problem. Or is there a problem in my coding practice that I am not following?

  • 1
    "However, I recently saw that using underscore and Hungarian notation is a not so good thing." Well, while it is generally recommended to avoid the Hungarian notation, many people make an exception and still use underscores or m_ to denote member variables. When it comes to naming conventions, it's less important which one you pick; what is important is that you pick one and that you stick to it consistently. (But, if you are joining a team on an existing project, switch to a convention they use.) – Filip Milovanović Aug 14 '17 at 8:31
  • @FilipMilovanović: I think the real problem here is not the usage of "underscores vs. some other convention". The problem is the OP tries to solve a problem which cannot be solved by a naming convention. – Doc Brown Aug 14 '17 at 10:31
  • Related: stackoverflow.com/questions/450238/… – Doc Brown Aug 14 '17 at 10:35
  • @DocBrown: I agree - my remark was was more of a side note about this specific concern (that's why I added it as a comment rather then as a full answer). – Filip Milovanović Aug 14 '17 at 13:51
7

By being able to differentiate, I would quickly know if I should use the property or the underlying variable to change/set the value.

No. By being able to differentiate, you quickly know that you can either use the property or the underlying variable, but not if which of the two you should use.

When you are writing code inside a class using a property or the "underlying variable" (if there is one), there are 3 possible cases:

  • using the property is correct, using the variable would be wrong (there is some logic in the property implemented which needs to be executed)
  • using the variable is correct, using the property would be wrong (there is some logic in the property which you explictly don't want to be executed)
  • it does not matter (there is no logic, you could probably use an automatic property instead).

(see, for example, this older SO post).

So whenever the variable in code shall be used, one needs to think about it which of the three cases applies, and act accordingly. No braindead naming convention can replace the need for making a sensible "per case" decision, and it does not matter if one uses an "underscore" to distinguish a property from a variable, or upper/lower case of the first character of the variable name, or some other prefix/postfix convention.

The best "coding practice" to manage this is by keeping classes small, readable and maintainable, so one can more easily decide if the logic needs to be executed or not.

  • Corollary to "best coding practice": preferring non-member functions increases the encapsulation of a class – Caleth Aug 14 '17 at 8:28
  • "preferring non-member functions increases [...] encapsulation" - Yes, but I'd just like to add this as a side note: in an OO system, these non-member functions would very likely be members of other classes; so this advice is really about properly distributing responsibilities across a number of classes (i.e. it's stems from the Single Responsibility Principle of SOLID). – Filip Milovanović Aug 14 '17 at 8:39
  • @FilipMilovanović In "a system where classes are the unit of code enclosure", not "an OO system". A language can be OO and still have free functions: see JavaScript, Python, C++ etc – Caleth Aug 14 '17 at 9:59
  • @Caleth: It can. It doesn't really matter, though - I wasn't talking about languages; I was talking about systems that are predominantly decomposed into interacting objects (and thus are object-oriented in design). It is true that I mentioned classes, but that's mainly because the OP is using C#. I also acknowledge that the Effective C++ item you pointed to do does not presume classes as primary organizational units (or OOP for that matter). – Filip Milovanović Aug 14 '17 at 14:18
  • @FilipMilovanović, Caleth I think the chatroom would be a much better place for your discussion. – Doc Brown Aug 14 '17 at 14:59
0

What are the alternatives to this problem.

I believe one of the best ways to avoid the issues arising from mixing up properties and private variables is the Integration Operation Separation Principle (maybe one of the lesser known principles in software development), which can be seen as an extension of the Single Responsibility Principle or the Single Level of Abstraction Principle.

You separate your code into methods that integrate (i.e. call other methods from the same codebase - which can be extended to properties, since they are methods at last) and those that operate (i.e. implement logic, call API methods) and avoid to mix up those two.

Adhering to this principle will force you to think about the usage of your properties and use them correctly.

Two side notes: First: Test! Tests will increase the confidence in the code written and most likely be able to catch the errors from the mis-use of the backing fields. Second: It sounds to me as if your classes get too big if you're in danger to mix backing fields and "normal" private fields up. Keep your classes small and adhere to the Single Responsibility Principle.

  • 1
    Describing the “Integration Operation Separation Principle” as “lesser known” might be an understatement, all I can find about it are a few mentions in a handful of blog posts or discussions in German or Hungarian. Your answer may be the first English-language explanation to ever be written! Can you recommend any resources that discuss this idea more thoroughly? – amon Aug 14 '17 at 13:35
0

These days, scope, type, and other information is easily obtained from the IDE. So you don't need to communicate any of that in a prefix any more.

It is more important these days for a programmer to be able to find your symbol in the intellisense list. And if you put an underscore before it, he may not, because it'll be sorted separately.

A backing field should be in camelCase with no underscore. The matching property should be in PascalCase. That way they are next to each other in the intellisense, and the programmer can see that immediately.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.