This question already has answers here:
Why use getters and setters/accessors?
(37 answers)
Closed 8 years ago.
Getters and Setters are bad
Briefly reading over the above article I find that getters and setters are bad OO design and should be avoided as they go against Encapsulation and Data Hiding. As this is the case how can it be avoided when creating objects and how can one model objects to take this into account.
In cases where a getter or setter is required what other alternatives can be used?
Thanks.
You have missed the point. The valid, important bit of that article is:
Don't ask for the information you need
to do the work; ask the object that
has the information to do the work for
you.
Java-style getter and setter proliferation are symptoms of ignoring this advice.
Getters or setters by themselves are not bad OO design.
What is bad is coding practice which includes a getter AND a setter for EVERY single member automatically, whether that getter/setter is needed or not (coupled with making members public which should not be public) - because this basically exposes class's implementation to outside world violating the information hiding/abstraction. Sometimes this is done automatically by IDE, which means such practice is significantly more widespread than it's hoped for.
Yes, getters and setters is an anti-pattern in OOP: http://www.yegor256.com/2014/09/16/getters-and-setters-are-evil.html. In a nutshell, they don't fit into object-oriented paradigm because they encourage you to treat an object like a data structure. Which is a major misconception.
You may find more details in my book Elegant Objects.
I believe in including setters in the API only if they are really part of the class specification (i.e. its contract with the caller).
Any other data member related to inner representation should be hidden, and I see at least 2 major reasons for that:
1) If inner representation is exposed, design changes are more problematic in the future, and require API changes as well.
2) Exposing data members with setters/getters with no caution allows callers to ruin the class invariant very easily. Objects with inconsistent state can cause bugs which are very difficult to analyze.
Unfortunately there are some frameworks which encourage (sometimes require) adding setters/getters for everything.
Getters and setters are not bad by themselves. What is bad is the practice of making any field to be private and provide getters/setters for all of them no matter what.
The way I read it, the author argues that blindly putting getters and setters around fields is no better than just making the field public.
I believe that the author argues that getters and setters should be placed sparsely, and with care, because the idea of OO is that objects should limit their exposure to what is needed only.
I'll go a bit further and say only value types should have getters. Each value type should be immutable and come with a builder which is mutable and has setters.
If your value type has setters they should return a new instance after copying the other values.
Url.setAnchor(...)
Would return a new Url copying the host port etc but overwrite the anchor.
Your service type classes don't need setters ( set them in ctor) and definitely font need getters. Your Mailer should take the host/port/etc static stuff in it's ctor. If I wish to send an email then I cell it's send(), there is no reason why my code should need to know or want or require the host and other config values. That said it would make sense to create a MailServer class like the following
// value type
MsilServer{
String host
int port
String username
Strung password // all come ruth getters
}
// factory
Mailer create( MailServer)
Getters and setters are just methods. What do they do? They change a field into a property, and that's an important distinction.
A field is a bit of data, of state, in the object. A property is an externally observable characteristic, part of the contract of the object. Spraying the guts of an object all over the place, whether directly or through getters/setters, is always a bad idea. Poor design. But raising that to the point of saying that getters and setters are always bad? That's just some poor programmer without a sense of good taste claiming that a vague rule of thumb (which they didn't really understand in the first place) is a cast iron law.
Personally, I tend to go for trying to keep properties as being things that don't change unexpectedly underneath the clients' feet. (Clients of the class that is.) The only properties that I'll change dynamically are ones they can't write, and even then I'll try to avoid it. I feel that properties are in many ways values that control the behaviour of the instance which are set by the client, not arbitrary things under the control of the class. (That's what normal field is for...)
I suggest that you read the whole article carefully as it presents well thought out arguments and alternatives. The question itself is too open ended and the answers you get here will be just more opinions.
From the article:
When is an accessor okay? First, as I
discussed earlier, it's okay for a
method to return an object in terms of
an interface that the object
implements because that interface
isolates you from changes to the
implementing class. This sort of
method (that returns an interface
reference) is not really a "getter" in
the sense of a method that just
provides access to a field. If you
change the provider's internal
implementation, you just change the
returned object's definition to
accommodate the changes. You still
protect the external code that uses
the object through its interface.
In other words, use interfaces for both getter and setter methods when they are necessary that way you can maintain encapsulation. It is good practice in general to specify an interface for a return type or formal parameter.
There are other articles that say they are good design.
But the answer is this:
getXXX and setXXX are good or bad based on usage.
these mathods do make a lot of things easier. So if some article says it's a bad design I think; it's just trying to be too hard on the idea.
One of the biggest usage of these methods are in a lot of framework and used as a reflection mechanism.
So don't completely avoid using these, rather... use it judiciously.
thanks
Ayusman
Getters and Setters are bad OO design?
Only when used without thinking.
If you're to create a value-object to transport data, they're fine.
If you're creating a more important object then they shouldn't be there. Take a look at the ArrayList interface* for instance. You don't see Object[] getElementData() because that would break the encapsulation ( some one may temper the underlying array ) .
* Im referring to the public interface of the class ( the methods exposed by the class definition )
Getters/Setters are perfectly appropriate, in the right conditions. However, mass Get/Set is wrong.
However, I'm a tad confused. You tagged Java but the material isn't really particularly Java specific (only the examples). It's worth noting that in C++ (best done in 0x) many of these issues don't exist. If you wanted to change your interface from long to int, then between decltype, templates and auto this is easily achievable, which is why such constructs rock. Typedef works well too.
Related
I came across with an article about proper way of encapsulation. It really got my attention and solved some of my prior confusion. Then I thought about it's implementation. There must not be any property or ( getter method ) that expose any common reference. In order to achieve this, each inner field must be constructed freshly. But it is not always possible to know construction logic or even find a proper constructor. So I thought that deep cloning might be used for this purpose.
There are some ways to achieve deep cloning ( one way, some other ways ).
My questions are:
1- Does my approach make sense or is it completely nonsense?
2- Are deep cloning operations dangerous or uncertain? If yes, would it be proper to use such dynamic ( or uncertain) behaviors for such a core module ( on business models getters )?
PS: Even if Java is used in the article, I ask questions for .NET or C#. I am not really sure but Java might have different deep cloning ability. I don't feel comfortable with Java.
Java and C# are close enough where the implications are the same.
To me, this article would be better left off unpublished, as the only thing it serves is to confuse people and send them down paths like "I need to deep clone all my exposed objects in an interface so they can't be changed."
This is not the essence of encapsulation. The essence of encapsulation is such that - for example - the calculation for an age, given a public birthdate, is not exposed:
class foo {
public DateTime Birthdate { get;set;}
public int Age { get { return (DateTime.Now - Birthdate).ToYears(); } }
}
Thus, the "inner workings" of how an age is calculated is not exposed. Or rather, that logic is encapsulated
Now, there may be times where you really do want to make sure an exposed object is entirely immutable, but on the general, that's rubbish. (deep cloning is no simple feat, at all, and this article doesn't give enough insight to the more broad scope of the problem to do anyone any good).
Drop the idea of deep cloning everything that gets exposed, and just write your classes with the logic contained within, and you'll have encapsulation well enough for the vast majority of purposes.
OOP concepts should always be taken with a very healthy dose of pragmatism.
When I have automatic propertie and I try to access it from within it's class, it seems like an overhead, because I use a function to access a member of my class instead of just accessing it directlly.
If this is correct, maybe I should consider not to use automatic properties in such cases?
Have you measured any theoretical overhead and found it to be significant? That's the key to making performance-based decisions.
In this case, I'd thoroughly expect the JIT to inline automatically-implemented properties, removing any performance overhead. (I seem to remember seeing a case with float / double where this wasn't the case, but that was a while ago - and even then the overhead was pretty small.)
Automatic properties are no different from ordinary properties in this regard.
Don't worry about it; the JITter will typically inline the property methods anyway.
You are right on that. However, some mechanisms need properties, for example XML serializer won't serialize public members...
Other thing is encapsulation - you never know in advance what is the final destination of each property of your class, so if you create it as property at first, you can go into set/get implementation later.
If you are following Object Oriented Principles, you would violate the Principle of Encapsulation by allowing access to your internal members directly. The Property mechanism (getters and setters methods) provide the proper access to these members protecting the internal members from direct access.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
When a property is read from or is assigned to, one would not expect it to perform a lot of work. When setSomeValue(...) and getSomeValue(...) methods are used instead, one should not be that surprised that something non-trivial might be going on under the hood. However, now that C# gave the world Properties, it seems silly to use getter and setter methods instead. What is your take on this? Should I mark this Q as a community wiki?
Thanks.
EDIT:
In my case it is not expensive to call, but it triggers setting a related property in another class and possibly writing a short message to a log file (if URL is blank). Is that too much work for a property? What is the alternative.
However, now that C# gave the world
Properties, it seems silly to use
getter and setter methods instead.
Before thinking about how expensive properties should be, I would advise you to think about whether the concept you are modeling is best represented as a "property of something". Properties exist in the language to express attribution of other entities - if SomeValue is not logically a property of the type it belongs to, then you should consider using getter/setter methods instead.
Should properties in C# perform a lot
of work?
Having said that, it helps to make properties inexpensive when possible. Most developers expect properties to be efficient wrappers around some internal state of the type they belong to. Violating this expectation makes it harder for developers to write well performing code that uses the property. For example, if a property is used in as a condition of a for loop it will be evaluated on each iteration - if it's expensive ... well that can be bad.
Properties are also often accessed in the debugger - you don't want properties to perform expensive logic as this can inhibit debugging. Property getters that perform operations with side effects (like querying a database, for example) are generally a bad practice as well, because they can introduce heisenbugs when inspecting the behavior of an application in the debugger.
What is the alternative.
You may also want to read up on this answer which provides some good general guidelines for property design. I would also advise you to read Choosing Between Properties and Methods in the .NET design guidelines on MSDN.
Sometimes it makes sense to create a property which is read-only (no setter) but where one or more separate methods exist that set the internal state related to that property. Whether to use this idiom depends on whether the operations on your object are exposed semantically as "changing state" or "performing activity". When it's the latter, I tend to use methods (rather than property setters) to express this behavior.
The general rule of thumb is properties should not be expensive to call. If they are expensive to call, make them into a getter instead. This can't always be followed, you definitely need to use judgment.
The exact amount of too much work is debatable. The best answer is that properties should rather perform less work than more work :)
One thing that Get Properties should never do is to change the state of the object.
methods are used instead, one should not be that surprised that something non-trivial might be going on under the hood
due to Properties is just a syntactic sugar over exactly the same Set... and Get... methods (which produced by compiler when IL is made) - there is no any difference. If you would implement some logic in SetFoobar - do it in Foobar { set { ... } } too
The person using the class you created has no idea as to what is the implementation. He might use User.ID over and over again without knowing each of those is a DB call.
You see, 99% of the time, properties are nothing more than variables with an extra line of code at best, so developers treat them as such. It's considered good practice to refactor a property into a method if it's expensive in any way. You never know what a method is hiding, and (good) developers conserve on calling methods when they can cache results from previous callings.
no, properties shouldn't perform a lot of work ...
"Should" they? That's a squishy question.
They certainly can, and there aren't a "lot" of reasons not to. Stack overflows are one good reason to avoid doing a lot of work inside a property accessor, but if your code is otherwise readable and your intent easily communicable, there's no hard and fast rule that says not to.
Properties are really just syntactic sugar. As a best practice I like to keep them very simple and not put a lot of code in them. However there is no technical reason for that. In the end they are just functions that get executed. What you need to ask when you use them is what is going to be most maintainable and intuitive to those who come after you.
As a user of a class, I expect properties to be not expensive - because as the name implies they just get/set a value of an object. In contrast, when I call a method on an object, I am aware that it will "do something" and might be expensive.
One thing, that should always be true for properties, is that property-getter should be free of side-effects. E.g. a property-getter should return the same value, even if I call it 10 successive times. This is best visible when you see this usage of a property:
int result = obj.SomeNumber + obj.SomeNumber;
// I expect SomeNumber to return the same value on both calls
I think the best rule to go by is that they shouldn't throw ecxeptions, and also don't have side effects. For example if you keep calling the getter, and nothing else changes the returned value shouldn't change. Note that ‘DateTime.Now‘ doesn't follow this rule, but probably should have.
In his excellent book, CLR Via C#, Jeffrey Richter said that he doesn't like properties, and recommends not to use them. He gave some reason, but I don't really understand. Can anyone explain to me why I should or should not use properties?
In C# 3.0, with automatic properties, does this change?
As a reference, I added Jeffrey Richter's opinions:
• A property may be read-only or write-only; field access is always readable and writable.
If you define a property, it is best to offer both get and set accessor methods.
• A property method may throw an exception; field access never throws an exception.
• A property cannot be passed as an out or ref parameter to a method; a field can. For
example, the following code will not compile:
using System;
public sealed class SomeType
{
private static String Name
{
get { return null; }
set {}
}
static void MethodWithOutParam(out String n) { n = null; }
public static void Main()
{
// For the line of code below, the C# compiler emits the following:
// error CS0206: A property or indexer may not
// be passed as an out or ref parameter
MethodWithOutParam(out Name);
}
}
• A property method can take a long time to execute; field access always completes immediately.
A common reason to use properties is to perform thread synchronization, which
can stop the thread forever, and therefore, a property should not be used if thread synchronization
is required. In that situation, a method is preferred. Also, if your class can be
accessed remotely (for example, your class is derived from System.MashalByRefObject),
calling the property method will be very slow, and therefore, a method is preferred to a
property. In my opinion, classes derived from MarshalByRefObject should never use
properties.
• If called multiple times in a row, a property method may return a different value each
time; a field returns the same value each time. The System.DateTime class has a readonly
Now property that returns the current date and time. Each time you query this
property, it will return a different value. This is a mistake, and Microsoft wishes that they
could fix the class by making Now a method instead of a property.
• A property method may cause observable side effects; field access never does. In other
words, a user of a type should be able to set various properties defined by a type in any
order he or she chooses without noticing any different behavior in the type.
• A property method may require additional memory or return a reference to something
that is not actually part of the object's state, so modifying the returned object has no
effect on the original object; querying a field always returns a reference to an object that
is guaranteed to be part of the original object's state. Working with a property that
returns a copy can be very confusing to developers, and this characteristic is frequently
not documented.
Jeff's reason for disliking properties is because they look like fields - so developers who don't understand the difference will treat them as if they're fields, assuming that they'll be cheap to execute etc.
Personally I disagree with him on this particular point - I find properties make the client code much simpler to read than the equivalent method calls. I agree that developers need to know that properties are basically methods in disguise - but I think that educating developers about that is better than making code harder to read using methods. (In particular, having seen Java code with several getters and setters being called in the same statement, I know that the equivalent C# code would be a lot simpler to read. The Law of Demeter is all very well in theory, but sometimes foo.Name.Length really is the right thing to use...)
(And no, automatically implemented properties don't really change any of this.)
This is slightly like the arguments against using extension methods - I can understand the reasoning, but the practical benefit (when used sparingly) outweighs the downside in my view.
Well, lets take his arguments one by one:
A property may be read-only or
write-only; field access is always
readable and writable.
This is a win for properties, since you have more fine-grained control of access.
A property method may throw an
exception; field access never throws
an exception.
While this is mostly true, you can very well call a method on a not initialized object field, and have an exception thrown.
• A property cannot be passed as an
out or ref parameter to a method; a
field can.
Fair.
• A property method can take a long
time to execute; field access always
completes immediately.
It can also take very little time.
• If called multiple times in a row, a
property method may return a different
value each time; a field returns the
same value each time.
Not true. How do you know the field's value has not changed (possibly by another thread)?
The System.DateTime class has a
readonly Now property that returns the
current date and time. Each time you
query this property, it will return a
different value. This is a mistake,
and Microsoft wishes that they could
fix the class by making Now a method
instead of a property.
If it is a mistake it's a minor one.
• A property method may cause
observable side effects; field access
never does. In other words, a user of
a type should be able to set various
properties defined by a type in any
order he or she chooses without
noticing any different behavior in the
type.
Fair.
• A property method may require
additional memory or return a
reference to something that is not
actually part of the object's state,
so modifying the returned object has
no effect on the original object;
querying a field always returns a
reference to an object that is
guaranteed to be part of the original
object's state. Working with a
property that returns a copy can be
very confusing to developers, and this
characteristic is frequently not
documented.
Most of the protestations could be said for Java's getters and setters too --and we had them for quite a while without such problems in practice.
I think most of the problems could be solved by better syntax highlighting (i.e differentiating properties from fields) so the programmer knows what to expect.
I haven't read the book, and you haven't quoted the part of it you don't understand, so I'll have to guess.
Some people dislike properties because they can make your code do surprising things.
If I type Foo.Bar, people reading it will normally expect that this is simply accessing a member field of the Foo class. It's a cheap, almost free, operation, and it's deterministic. I can call it over and over, and get the same result every time.
Instead, with properties, it might actually be a function call. It might be an infinite loop. It might open a database connection. It might return different values every time I access it.
It is a similar argument to why Linus hates C++. Your code can act surprising to the reader. He hates operator overloading: a + b doesn't necessarily mean simple addition. It may mean some hugely complicated operation, just like C# properties. It may have side effects. It may do anything.
Honestly, I think this is a weak argument. Both languages are full of things like this. (Should we avoid operator overloading in C# as well? After all, the same argument can be used there)
Properties allow abstraction. We can pretend that something is a regular field, and use it as if it was one, and not have to worry about what goes on behind the scenes.
That's usually considered a good thing, but it obviously relies on the programmer writing meaningful abstractions. Your properties should behave like fields. They shouldn't have side effects, they shouldn't perform expensive or unsafe operations. We want to be able to think of them as fields.
However, I have another reason to find them less than perfect. They can not be passed by reference to other functions.
Fields can be passed as ref, allowing a called function to access it directly. Functions can be passed as delegates, allowing a called function to access it directly.
Properties... can't.
That sucks.
But that doesn't mean properties are evil or shouldn't be used. For many purposes, they're great.
Back in 2009, this advice merely seemed like bellyaching of the Who Moved My Cheese variety. Today, it's almost laughably obsolete.
One very important point that many answers seem to tiptoe around but don't quite address head on is that these purported "dangers" of properties are an intentional part of the framework design!
Yes, properties can:
Specify different access modifiers for the getter and setter. This is an advantage over fields. A common pattern is to have a public getter and a protected or internal setter, a very useful inheritance technique which isn't achievable by fields alone.
Throw an exception. To date, this remains one of the most effective methods of validation, especially when working with UI frameworks that involve data-binding concepts. It's much more difficult to ensure that an object remains in a valid state when working with fields.
Take a long time to execute. The valid comparison here is with methods, which take equally long - not fields. No basis is given for the statement "a method is preferred" other than one author's personal preference.
Return different values from its getter on subsequent executions. This almost seems like a joke in such close proximity to the point extolling the virtues of ref/out parameters with fields, whose value of a field after a ref/out call is pretty much guaranteed to be different from its previous value, and unpredictably so.
If we're talking about the specific (and practically academic) case of single-threaded access with no afferent couplings, it's fairly well understood that it's just bad property design to have visible-state-changing side-effects, and maybe my memory is fading, but I just can't seem to recall any examples of folks using DateTime.Now and expecting the same value to come out every time. At least not any instances where they wouldn't have screwed it up just as badly with a hypothetical DateTime.Now().
Cause observable side effects - which is of course precisely the reason properties were invented as a language feature in the first place. Microsoft's own Property Design guidelines indicate that setter order shouldn't matter, as to do otherwise would imply temporal coupling. Certainly, you can't achieve temporal coupling with fields alone, but that's only because you can't cause any meaningful behaviour at all to happen with fields alone, until some method is executed.
Property accessors can actually help prevent certain types of temporal coupling by forcing the object into a valid state before any action is taken - for example, if a class has a StartDate and an EndDate, then setting the EndDate before the StartDate could force the StartDate back as well. This is true even in multi-threaded or asynchronous environments, including the obvious example of an event-driven user interface.
Other things that properties can do which fields can't include:
Lazy loading, one of the most effective ways of preventing initialization-order errors.
Change Notifications, which are pretty much the entire basis for the MVVM architecture.
Inheritance, for example defining an abstract Type or Name so derived classes can provide interesting but nevertheless constant metadata about themselves.
Interception, thanks to the above.
Indexers, which everyone who has ever had to work with COM interop and the inevitable spew of Item(i) calls will recognize as a wonderful thing.
Work with PropertyDescriptor which is essential for creating designers and for XAML frameworks in general.
Richter is clearly a prolific author and knows a lot about the CLR and C#, but I have to say, it seems like when he originally wrote this advice (I'm not sure if it's in his more recent revisions - I sincerely hope not) that he just didn't want to let go of old habits and was having trouble accepting the conventions of C# (vs. C++, for example).
What I mean by this is, his "properties considered harmful" argument essentially boils down to a single statement: Properties look like fields, but they might not act like fields. And the problem with the statement is, it isn't true, or at best it's highly misleading. Properties don't look like fields - at least, they aren't supposed to look like fields.
There are two very strong coding conventions in C# with similar conventions shared by other CLR languages, and FXCop will scream at you if you don't follow them:
Fields should always be private, never public.
Fields should be declared in camelCase. Properties are PascalCase.
Thus, there is no ambiguity over whether Foo.Bar = 42 is a property accessor or a field accessor. It's a property accessor and should be treated like any other method - it might be slow, it might throw an exception, etc. That's the nature of Abstraction - it's entirely up to the discretion of the declaring class how to react. Class designers should apply the principle of least surprise but callers should not assume anything about a property except that it does what it says on the tin. That's on purpose.
The alternative to properties is getter/setter methods everywhere. That's the Java approach, and it's been controversial since the beginning. It's fine if that's your bag, but it's just not how we roll in the .NET camp. We try, at least within the confines of a statically-typed system, to avoid what Fowler calls Syntactic Noise. We don't want extra parentheses, extra get/set warts, or extra method signatures - not if we can avoid them without any loss of clarity.
Say whatever you like, but foo.Bar.Baz = quux.Answers[42] is always going to be a lot easier to read than foo.getBar().setBaz(quux.getAnswers().getItem(42)). And when you're reading thousands of lines of this a day, it makes a difference.
(And if your natural response to the above paragraph is to say, "sure it's hard to read, but it would be easier if you split it up in multiple lines", then I'm sorry to say that you have completely missed the point.)
I don't see any reasons why you shouldn't use Properties in general.
Automatic properties in C# 3+ only simplify syntax a bit (a la syntatic sugar).
It's just one person's opinion. I've read quite a few c# books and I've yet to see anyone else saying "don't use properties".
I personally think properties are one of the best things about c#. They allow you to expose state via whatever mechanism you like. You can lazily instantiate the first time something is used and you can do validation on setting a value etc. When using and writing them, I just think of properties as setters and getters which a much nicer syntax.
As for the caveats with properties, there are a couple. One is probably a misuse of properties, the other can be subtle.
Firstly, properties are types of methods. It can be surprising if you place complicated logic in a property because most users of a class will expect the property to be fairly lightweight.
E.g.
public class WorkerUsingMethod
{
// Explicitly obvious that calculation is being done here
public int CalculateResult()
{
return ExpensiveLongRunningCalculation();
}
}
public class WorkerUsingProperty
{
// Not at all obvious. Looks like it may just be returning a cached result.
public int Result
{
get { return ExpensiveLongRunningCalculation(); }
}
}
I find that using methods for these cases helps to make a distinction.
Secondly, and more importantly, properties can have side-effects if you evaluate them while debugging.
Say you have some property like this:
public int Result
{
get
{
m_numberQueries++;
return m_result;
}
}
Now suppose you have an exception that occurs when too many queries are made. Guess what happens when you start debugging and rollover the property in the debugger? Bad things. Avoid doing this! Looking at the property changes the state of the program.
These are the only caveats I have. I think the benefits of properties far outweigh the problems.
That reason must have been given within a very specific context. It's usually the other way round - it is recomended to use properties as they give you a level of abstraction enabling you to change behaviour of a class without affecting its clients...
I can't help picking on the details of Jeffrey Richter's opinions:
A property may be read-only or write-only; field access is always readable and writable.
Wrong: Fields can marked read-only so only the object's constructor can write to them.
A property method may throw an exception; field access never throws an exception.
Wrong: The implementation of a class can change the access modifier of a field from public to private. Attempts to read private fields at runtime will always result in an exception.
I don't agree with Jeffrey Richter, but I can guess why he doesn't like properties (I haven't read his book).
Even though, properties are just like methods (implementation-wise), as a user of a class, I expect that its properties behave "more or less" like a public field, e.g:
there's no time-consuming operation going on inside the property getter/setter
the property getter has no side effects (calling it multiple times, does not change the result)
Unfortunately, I have seen properties which did not behave that way. But the problem are not the properties themselves, but the people who implemented them. So it just requires some education.
The argument assumes that properties are bad because they look like fields, but can do surprising actions. This assumption is invalidated by .NET programmers' expectactions:
Properties don't look like fields. Fields look like properties.
• A property method may throw an exception; field access never throws an exception.
So, a field is like a property that is guaranteed to never throw an exception.
• A property cannot be passed as an out or ref parameter to a method; a field can.
So, a field is like a property, but it has additional capabilities: passing to a ref/out accepting methods.
• A property method can take a long time to execute; field access always completes immediately. [...]
So, a field is like a fast property.
• If called multiple times in a row, a property method may return a different value each time; a field returns the same value each time. The System.DateTime class has a readonly Now property that returns the current date and time.
So, a field is like a property that is guaranteed to return the same value unless the field was set to a different value.
• A property method may cause observable side effects; field access never does.
Again, a field is a property that is guaranteed to not do that.
• A property method may require additional memory or return a reference to something that is not actually part of the object's state, so modifying the returned object has no effect on the original object; querying a field always returns a reference to an object that is guaranteed to be part of the original object's state. Working with a property that returns a copy can be very confusing to developers, and this characteristic is frequently not documented.
This one may be surprising, but not because it's a property that does this. Rather, it's that barely anyone returns mutable copies in properties, so that 0.1% case is surprising.
There is a time when I consider not using properties, and that is in writing .Net Compact Framework code. The CF JIT compiler does not perform the same optimisation as the desktop JIT compiler and does not optimise simple property accessors, so in this case adding a simple property causes a small amount of code bloat over using a public field. Usually this wouldn't be an issue, but almost always in the Compact Framework world you are up against tight memory constraints, so even tiny savings like this do count.
You shouldn't avoid using them but you should use them with qualification and care, for the reasons given by other contributors.
I once saw a property called something like Customers that internally opened an out-of-process call to a database and read the customer list. The client code had a 'for (int i to Customers.Count)' which was causing a separate call to the database on each iteration and for the access of the selected Customer. That's an egregious example that demonstrates the principle of keeping the property very light - rarely more than a internal field access.
One argument FOR using properties is that they allow you to validate the value being set. Another is that the value of of the property may be a derived value, not a single field, like TotalValue = amount * quantity.
Personally I only use properties when creating simple get / set methods. I stray away from it when coming to complicated data structures.
I haven't read his book but I agree with him.
It's quite a contradiction on the usual paradigm.
They look like a field but had many sideeffects. Exceptions, performance, sideeffects, read/write access difference, etc.
If you care about readability and reliability i think you'd care about this as well.
In my experience i never gained anything from properties and only felt like using them when i was lazy.
But many times i encountered people using properties as if they were fields inadvertently creating all sort of issues.
Ive worked professionally on many languages for quite a time and never needed them, not even once.
Of course other people might find them useful and that's fine too.
Depends on your user case and what you value.
I personally believe they are just 'features ' that you can choose to use or not.
Invoking methods instead of properties greatly reduces the readability of the invoking code. In J#, for example, using ADO.NET was a nightmare because Java doesn't support properties and indexers (which are essentially properties with arguments). The resulting code was extremely ugly, with empty parentheses method calls all over the place.
The support for properties and indexers is one of the basic advantages of C# over Java.
There's a lot of advice out there that you shouldn't expose your fields publically, and instead use trivial properties. I see it over & over.
I understand the arguments, but I don't think it's good advice in most cases.
Does anyone have an example of a time when it really mattered? When writing a trivial property made something important possible in the future (or when failing to use one got them in to real trouble)?
EDIT: The DataBinding argument is correct, but not very interesting. It's a bug in the DataBinding code that it won't accept public fields. So, we have to write properties to work around that bug, not because properties are a wise class design choice.
EDIT: To be clear, I'm looking for real-world examples, not theory. A time when it really mattered.
EDIT: The ability to set a breakpoint on the setter seems valuable. Designing my code for the debugger is unfortunate: I'd rather the debugger get smarter, but given the debugger we have, I'll take this ability. Good stuff.
It may be hard to make code work in an uncertain future, but that's no excuse to be lazy. Coding a property over a field is convention and it's pragmatic. Call it defensive programming.
Other people will also complain that there's a speed issue, but the JIT'er is smart enough to make it just about as fast as exposing a public field. Fast enough that I'll never notice.
Some non-trivial things that come to mind
A public field is totally public, you can not impose read-only or write-only semantics
A property can have have different get versus set accessibility (e.g. public get, internal set)
You can not override a field, but you can have virtual properties.
Your class has no control over the public field
Your class can control the property. It can limit setting to allowable range of values, flag that the state was changed, and even lazy-load the value.
Reflection semantics differ. A public field is not a property.
No databinding, as others point out. (It's only a bug to you. - I can understand Why .net framework designers do not support patterns they are not in favour of.)
You can not put a field on an interface, but you can put a property on an interface.
Your property doesn't even need to store data. You can create a facade and dispatch to a contained object.
You only type an extra 13 characters for correctness. That hardly seems like speculative generality. There is a semantic difference, and if nothing else, a property has a different semantic meaning and is far more flexible than a public field.
public string Name { get; set; }
public string name;
I do recall one time when first using .net I coded a few classes as just fields, and then I needed to have them as properties for some reason, and it was a complete waste of time when I could have just done it right the first time.
So what reasons do you have for not following convention? Why do you feel the need to swim upstream? What has it saved you by not doing this?
I've had a trivial property save me a couple of times when debugging. .Net doesn't support the concept of a data break point (read or write). Occasionally when debugging a very complex scenario it was important to track read/writes to a particular property. This is easy with a property but impossible with a field.
If you're not working in a production environment, it's simple to refactor a field -> property for the purpose of debugging. Occasionally though you hit bugs that only reproduce in a production environment that is difficult to patch with a new binary. A property can save you here.
It's a fairly constrained scenario though.
I used to think the same thing, Jay. Why use a property if it's only there to provide direct access to a private member? If you can describe it as an autoproperty, having a property at all rather than a field seemed kind of silly. Even if you ever need to change the implementation, you could always just refactor into a real property later and any dependent code would still work, right?. Well, maybe not.
You see, I've recently seen the light on trivial properties, so maybe now I can help you do the same.
What finally convinced me was the fairly obvious point (in retrospect) that properties in .Net are just syntactic sugar for getter and setter methods, and those methods have a different name from the property itself. Code in the same assembly will still work, because you have to recompile it at the same time anyway. But any code in a different assembly that links to yours will fail if you refactor a field to a property, unless it's recompiled against your new version at the same time. If it's a property from the get-go, everything is still good.
I'll answer your question with another one: have you ever really benefited from not making all your types and members public? I suspect I haven't directly prevented any bugs by doing so. However, I've encapsulated my types properly, only exposing what's meant to be exposed. Properties are similar - good design more than anything else. I think of properties as conceptually different from fields; they're part of the contract rather than being fundamentally part of the implementation. Thinking about them as properties rather than fields helps me to think more clearly about my design, leading to better code.
Oh, and I've benefited occasionally from not breaking source compatibility, being able to set breakpoints, log access etc.
Part of the idea is that those properties may not be trivial in the future - if you bound external code to a field and later wanted to wrap that in a property, all of the dependent code would have to change, and you may not be able to do that, especially in the case where you are a control designer or have libraries that you can't control, etc.
Not to mention there are certain .NET practices that will not allow you to use a field - databinding particularly.
I am sure there are other good reasons as well. Why does it matter to you? Use an automatic property and be done with it. Seems like something not worth being concerned about to me...
It's much easier to debug a problem involving a field if it is wrapped by a property accessor. Placing breakpoints in the accessor can quite quickly help with finding re-entrancy and other issues that otherwise might not be caught. By marshaling all access to the field through an accessor, you can ascertain exactly who is changing what and when.
In .NET, from my understanding, you cannot databind to public fields; but only to properties. Thus, if you want to do databinding, you have no choice.
I once had fields that I wanted to expose from a windows from project which allowed the stats for the program (TotalItems and SuccessfulItems).
Later I decided to display the stats on the form and was able to add a call in the setter that updated the display when the property changed.
Obviously, if you're not creating a shared class library, and you're not using DataBinding, then using a field will cause you no problems whatsoever.
But if you're creating a shared class library, you'd be foolish IMHO to do otherwise than follow the guidelines, for the usual three reasons:
consumers of your shared class library may want to use DataBinding.
consumers of your shared class might want binary compatibility, which is not possible if you switch from a field to a property.
the principal of least surprise implies you should be consistent with other shared class libraries including the .NET Framework itself.
IMHO there is no such thing as a trivial property as people have been calling them. Via the way things such as databinding work, Microsoft has implied that any bit of data that is a part of the public interface of an object should be a property. I don't think they meant it merely to be a convention like it is in some other languages where property syntax is more about convention and convenience.
A more interesting question may be: "When should I use a public field instead of a property", or "When has a public field instead of a public property saved your bacon?"
Fields which are of structure types allow direct access to the members thereof, while properties of such types do not. Consequently, if Thing.Boz were a field of type Point, code which wants to modify its X value could simply say Thing.Boz.X += 5;; if Thing.Boz were a mutable property, it would be necessary to use var tmp = Thing.Boz; tmp.X += 5; Thing.Boz = tmp;. The ability to write things more cleanly with the exposed field is often, but not always, a blessing.
If it will always be possible for Boz to be a field, modifying its members directly will be cleaner, faster, and better than copying it to a temporary variable, modifying that, and copying it back. If the type of Boz exposes its mutable fields directly (as structures should) rather than wrapping them in trivial wrappers, it will also be possible to use things like Interlocked methods on them--something that's simply impossible with properties. There's really only one disadvantage to using fields in that way: if it's ever necessary to replace the field with a property, code which relied upon the thing being a field will break, and may be hard to fix.
In short, I would posit that in cases where one isn't concerned about being able to swap in different versions of code without having to recompile any consumers, the biggest effect of using properties rather than fields is to prevent consumers of the code from writing code which would take advantage of (and rely upon) the semantics of exposed fields which are of structure types.
Incidentally, an alternative to exposing a field of a structure type would be to expose an ActOnXXX method. For example:
delegate void ActionByRef<T1>(ref T1 p1);
delegate void ActionByRef<T1,T2>(ref T1 p1, ref T2 p2);
delegate void ActionByRef<T1,T2,T3>(ref T1 p1, ref T2 p2, ref T3 p3);
// Method within the type that defines property `Boz`
void ActOnBoz<T1>(ActionByRef<Point, T1> proc, ref T1 p1)
{
proc(ref _Boz, ref p1); // _Boz is the private backing field
}
Code which wanted to add some local variable q to Thing.Boz.X could call Thing.ActOnBoz((ref Point pt, ref int x) => {pt.X += x;}, ref q); and have the action performed directly on Thing._Boz, even though the field is not exposed.