views:

223

answers:

6

Now if you read the naming conventions in the MSDN for C# you will notice that it states that properties are always preferred over public and protected fields. I have even been told by some people that you should never use public or protected fields. Now I will agree I have yet to find a reason in which I need to have a public field but are protected fields really that bad?

I can see it if you need to make sure that certain validation checks are performed when getting/setting the value however a lot of the time it seems like just extra overhead in my opinion. I mean lets say I have a class class GameItem with fields for baseName, prefixName, and suffixName. Why should I take the overhead of both creating the properties (C#) or accessor methods and the performance hit I would occur (if I do this for ever single field in an application, I am sure that it would adds up at less a little especially in certain languages like PHP or certain applications with performance is critical like games)?

+17  A: 

Are protected members/fields really that bad?

No. They are way, way worse.

As soon as a member is more accessible than private, you are making guarantees to other classes about how that member will behave. Since a field is totally uncontrolled, putting it "out in the wild" opens your class and classes that inherit from or interact with your class to higher bug risk. There is no way to know when a field changes, no way to control who or what changes it.

If now, or at some point in the future, any of your code ever depends on a field some certain value, you now have to add validity checks and fallback logic in case it's not the expected value - every place you use it. That's a huge amount of wasted effort when you could've just made it a damn property instead ;)

The best way to share information with deriving classes is the read-only property:

protected object MyProperty { get; }

If you absolutely have to make it read/write, don't. If you really, really have to make it read-write, rethink your design. If you still need it to be read-write, apologize to your colleagues and don't do it again :)

A lot of developers believe - and will tell you - that this is overly strict. And it's true that you can get by just fine without being this strict. But taking this approach will help you go from just getting by to remarkably robust software. You'll spend far less time fixing bugs.

And regarding any concerns about performance - don't. I guarantee you will never, in your entire career, write code so fast that the bottleneck is the call stack itself.

Rex M
+1, more if I could. As soon as you make a member not-private, you are stuck with it, forever and ever. It's your public interface now.
Nikolai N Fetissov
I mostly agree but I see no problem having writable protected properties. After all it is just syntactic sugar for a method with a parameter and I don't think many people would argue that protected methods must not have any parameters. (I am ignoring the slight semantic differences when choosing between a method and a property for the moment.)
Daniel Brückner
@Daniel Making a property writable adds an order of magnitude in complexity. In the real world it's definitely not realistic for *every* class to be immutable, but if most of your classes are, it's remarkably easier to write bug-free code. I had that revelation once and I hope to help others have it.
Rex M
@Daniel (to clarify, I am distinguishing between properties as representing state and methods representing actions)
Rex M
I did forget that properties can be created easily with:protected int SomeProperty { get; set; }I am having a hard time understanding why properties should never be writable. I mean if properties should always only be read-only and fields should only be private, the only way to set a field value in a derived class is through the constructor (unless I am missing something).I do now see why making fields private all the time with public/protected properties (at least in C#) would be a good idea.
ryanzec
Okay, just advertising immutable types. A good thing, keep going!
Daniel Brückner
@Daniel (also to clarify, by immutable I mean externally immutable - that is, consumers cannot affect the state. The class can internally affect its own state)
Rex M
@ryanzec you nailed it! A consumer should only be able to set an object's state at initialization (via the constructor). Once the object has come to life, it should be internally responsible for its own state lifecycle. Allowing consumers to affect the state adds unnecessary complexity and risk.
Rex M
@Daniel, no, protected writable properties is about the worst design choice you can make. Combined with over-obuse of inheritance these quickly become a nightmare. I've seen people make mutex variables protected in large inheritance chains. Try debugging that in any non-trivial project.
Nikolai N Fetissov
@Rex M Based on your previous comments (ones I did not see before my comment), I can see that have the goal of only read-only properties is good. To me though, that would not be a very strict guideline (like making sure to have no public fields) but diffidently something to think about that can lead to better code design.
ryanzec
+4  A: 

Regarding fields vs. properties, I can think of two reasons for prefering properties in the public interface (protected is also public in the sense that someone else than just your class can see it).

  • Exposing properties gives you a way to hide the implementation. It also allows you to change the implementation without changing the code that uses it (e.g. if you decide to change the way data are stored in the class)

  • Many tools that work with classes using reflection only focus on properties (for example, I think that some libraries for serialization work this way). Using properties consistently makes it easier to use these standard .NET tools.

Regarding overheads:

  • If the getter/setter is the usual one line piece of code that simply reads/sets the value of a field, then the JIT should be able to inline the call, so there is no performance overhad.

  • Syntactical overhead is largely reduced when you're using automatically implemented properties (C# 3.0 and newer), so I don't think this is an issue:

    protected int SomeProperty { get; set; }
    

    In fact, this allows you to make for example set protected and get public very easily, so this can be even more elegant than using fields.

Tomas Petricek
+3  A: 

Public and/or protected fields are bad because they can be manipulated from outside the declaring class without validation; thus they can be said to break the encapsulation principle of object oriented programming.

When you lose encapsulation, you lose the contract of the declaring class; you cannot guarantee that the class behaves as intended or expected.

Using a property or a method to access the field enables you to maintain encapsulation, and fulfill the contract of the declaring class.

Håvard S
A: 

I agree with the read-only property answer. But to play devil's advocate here, it really depends on what you're doing. I'll be happy to admit i write code with public members all the time (i also don't comment, follow guidelines, or any of the formalities).

But when i'm at work that's a different story.

AlvinfromDiaspar
+7  A: 

OK, downvote time.

  • First of all, properties will never hurt performance (provided they don't do much). That's what everyone else says, and I agree.

  • Another point is that properties are good in that you can place breakpoints in them to capture getting/setting events and find out where they come from.

The rest of the arguments bother me in this way:

  • They sound like "argument by prestige". If MSDN says it, or some famous developer or author whom everybody likes says it, it must be so.

  • They are based on the idea that data structures have lots of inconsistent states, and must be protected against wandering or being placed into those states. Since (it seems to me) data structures are way over-emphasized in current teaching, then typically they do need those protections. Far more preferable is to minimize data structure so that it tends to be normalized and not to have inconsistent states. Then, if a member of a class is changed, it is simply changed, rather than damaged. After all, somehow lots of good software was/is written in C, and that didn't suffer massively from lack of protections.

  • They are based on defensive coding carried to extremes. It is based on the idea that your classes will be used in a world where nobody else's code can be trusted not to goose your stuff. I'm sure there are situations where this is true, but I've never seen them. What I have seen is situations where things were made horribly complicated to get around protections for which there was no need, and to try to guard the consistency of data structures that were horribly over-complicated and un-normalized.

Mike Dunlavey
Very good points. I would only raise one thought: if you work on a team of more than 1, then your code is in the wild. Anything that isn't explicitly enforced by contract is vulnerable to misunderstandings. It's doing your teammates a great service, and reducing everyone's effort, by eliminating ambiguity and enforcing information flow by design.
Rex M
Python essentially doesn't _have_ private methods, let alone protected ones, and it doesn't turn out to be that big a deal in practice.
Chris B.
@Rex: I know that's the accepted wisdom, and I can certainly understand it, but it still strikes me as something people believe in the abstract, rather than know from hard experience. I've always found that if you look behind/under widely held beliefs, you can find useful gems. (BTW I do work in a good-size team.)
Mike Dunlavey
@Mike maybe most people only believe it in the abstract, but since I've started living it, and making it policy for my team, life has gotten much more pleasant. Output is up, bug rate is down, and happiness is up. Changing to work that way is a tough hill to climb, no question. IMO it's more than worth it.
Rex M
@Rex: OK, no contest.
Mike Dunlavey
A: 

It actually depends on if your class is a data class or a behaviour class.

If you keep your behaviour and data separate, it is fine to expose the data of your data classes, as long as they have no behaviour.

If the class is a behaviour class, then it should not expose any data.

Mongus Pong