views:

62

answers:

7

Possible Duplicate:
Public Data members vs Getters, Setters

In what cases should public fields be used, instead of properties or getter and setter methods (where there is no support for properties)? Where exactly is their use recommended, and why, or, if it is not, why are they still allowed as a language feature? After all, they break the Object-Oriented principle of encapsulation where getters and setters are allowed and encouraged.

+4  A: 

If you have a constant that needs to be public, you might as well make it a public field instead of creating a getter property for it.

Apart from that, I don't see a need, as far as good OOP principles are concerned.

They are there and allowed because sometimes you need the flexibility.

Oded
+1 for reading my mind :)
Niels van der Rest
I'm not sure if a public constant is always desirable. Such a value is part of the API from this point on and you possibly cannot remove/alter it easily.
soulmerge
+1  A: 

If your compiler does not optimize getter and setter invocations, the access to your properties might be more expensive than reading and writing fields (call stack). That might be relevant if you perform many, many invocations.

But, to be honest, I know no language where this is true. At least in both .NET and Java this is optimized well.

From a design point of view I know no case where using fields is recommended...

Cheers Matthias

Mudu
+1  A: 

Rico Mariani mentions some cases where fields have some advantages over properties, but note that these are really exceptional cases and usually properties should be used:

Performance Quiz #11: Ten Questions on Value-Based Programming : Solution

0xA3
+1  A: 

That's hard to tell, but in my opinion public fields are only valid when using structs.

struct Simple
{
    public int Position;
    public bool Exists;
    public double LastValue;
};

But different people have different thoughts about:

http://kristofverbiest.blogspot.com/2007/02/public-fields-and-properties-are-not.html

http://blogs.msdn.com/b/ericgu/archive/2007/02/01/properties-vs-public-fields-redux.aspx

http://www.markhneedham.com/blog/2009/02/04/c-public-fields-vs-automatic-properties/

BitKFu
A: 

Let's first look at the question why we need accessors (getters/setters)? You need them to be able to override the behaviour when assigning a new value/reading a value. You might want to add caching or return a calculated value instead of a property.

Your question can now be formed as do I always want this behaviour? I can think of cases where this is not useful at all: structures (what were structs in C). Passing a parameter object or a class wrapping multiple values to be inserted into a Collection are cases where one actually does not need accessors: The object is merely a container for variables.

soulmerge
A: 

There is one single reason(*) why to use get instead of public field: lazy evaluation. I.e. the value you want may be stored in a database, or may be long to compute, and don't want your program to initialize it at startup, but only when needed.

There is one single reason(*) why to use set instead of public field: other fields modifications. I.e. you change the value of other fields when you the value of the target field changes.

Forcing to use get and set on every field is in contradiction with the YAGNI principle.

If you want to expose the value of a field from an object, then expose it! It is completely pointless to create an object with four independent fields and mandating that all of them uses get/set or properties access.

*: Other reasons such as possible data type change are pointless. In fact, wherever you use a = o.get_value() instead of a = o.value, if you change the type returned by get_value() you have to change at every use, just as if you would have changed the type of value.

Didier Trosset
I don't think YAGNI goes so far as "maybe calling code ain't going to need to work when we release a later version of this component". I'd be pretty sure they are going to need it, and so you do have to think about whether you might need to change a field to a property up-front as such a change will break calling code.
Jon Hanna
Just as you wrote, you're *pretty sure*. YAGNI tells that until you actually need it, you don't write it.
Didier Trosset
I said "pretty sure" for humour value. I'm 100% certain that if I upgrade a component and lots of other components stop working, that I won't be happy. I don't know if I'm going to need a given change, but if its impossible to make that change without breaking running code, then there are limits on YAGNI.
Jon Hanna
A: 

The main reason is nothing to do with OOP encapsulation (though people often say it is), and everything to do with versioning.

Indeed from the OOP position one could argue that fields are better than "blind" properties, as a lack of encapsulation is clearer than something that pretends to encapsulation and then blows it away. If encapsulation is important, then it should be good to see when it isn't there.

A property called Foo will not be treated the same from the outside as a public field called Foo. In some languages this is explicit (the language doesn't directly support properties, so you've got a getFoo and a setFoo) and in some it is implicit (C# and VB.NET directly support properties, but they are not binary-compatible with fields and code compiled to use a field will break if it's changed to a property, and vice-versa).

If your Foo just does a "blind" set and write of an underlying field, then there is currently no encapsulation advantage to this over exposing the field.

However, if there is a later requirement to take advantage of encapsulation to prevent invalid values (you should always prevent invalid values, but maybe you didn't realise some where invalid when you first wrote the class, or maybe "valid" has changed with a scope change), to wrap memoised evaluation, to trigger other changes in the object, to trigger an on-change event, to prevent expensive needless equivalent sets, and so on, then you can't make that change without breaking running code.

If the class is internal to the component in question, this isn't a concern, and I'd say use fields if fields read sensibly under the general YAGNI principle. However, YAGNI doesn't play quite so well across component boundaries (if I did need my component to work today, I certainly am probably going to need that it works tomorrow after you've changed your component that mine depends on), so it can make sense to pre-emptively use properties.

Jon Hanna