Should I use "this" to call class properties, members, or methods? - c#

I've seen some guides or blogs that say using this to access a class's own members is bad. However, I've also seen some places where professionals are accessing with this. I tend to prefer explicitly using this, since it seems to make it clear that the thing I'm accessing is part of the class.
this.MyProperty = this.GetSomeValue();
Is there some advantage or disadvantage to using this? Is it simply a stylistic preference?

If it adds to the clarity of the code, use it , if it doesn't don't. There are a few places it does add clarity - for example in C++:
struct Point {
int x, y;
Point & operator=( const Point & p ) {
this->x = p.x;
this->y = p.y;
return *this;
}
};
In cases like this, when you have two objects of the same type to refer to I find that the use of this can clarify things (though note that in C++ the above assignment operator implementation is not necessary).

I always use this. because it makes code more readable in my opinion. It makes instantly clear that
It's a member of this instance.
Clarifies if base class is called (base.) or the overriding member (this.)
It's not a static member.
It's not a call to a member of another static class (this.Monster.Legs.Run(); vs Monster.Legs.Run();).

Having gone from using this for years, to finding not many people (atleast in my experience) use it, I eventually changed. The benefits I can see of having this-less code:
I use underscores: _myVar for private variables, which don't need a this as they're always member variables.
For method calls it is very obvious that it's part of the class. You would prepend the type name if it wasn't.
(C#) Private variables and parameters are always camel case.
If your class is so big it's getting confusing you've got an issue with cohesion and separation of concerns anyway.
(C#) Visual Studio color codes types, so you know if you're using a property or type:
e.g.
someclass.Method(1);
SomeClass.StaticMethod(1);
I can see that if you don't use the underscores naming convention, and have a large method with a weighty body it could lead to some confusion.
Static methods or properties can occasionally confuse things, but very rarely.
You will obviously always need the this keyword when passing references, for example:
someclass.Method(this);
var someclass = new SomeClass(this);
(I write C#, but my answer relates to Java)

It's sometimes necessary, e.g. in a constructor (in C# or Java) if you are assigning a field from a parameter of the same name.

I use this, because it seems more readable to me. And...
StyleCop rule SA1101: PrefixLocalCallsWithThis says:
Cause
A call to an instance member of the local class or a base class is not prefixed with ‘this.’, within a C# code file.
Rule Description
A violation of this rule occurs whenever the code contains a call to an instance member of the local class or a base class which is not prefixed with ‘this.’. An exception to this rule occurs when there is a local override of a base class member, and the code intends to call the base class member directly, bypassing the local override. In this case the call can be prefixed with ‘base.’ rather than ‘this.’.
By default, StyleCop disallows the use of underscores or m_ to mark local class fields, in favor of the ‘this.’ prefix. The advantage of using ‘this.’ is that it applies equally to all element types including methods, properties, etc., and not just fields, making all calls to class members instantly recognizable, regardless of which editor is being used to view the code. Another advantage is that it creates a quick, recognizable differentiation between instance members and static members, which are not be prefixed.
A final advantage of using the ‘this.’ prefix is that typing this. will cause Visual Studio to show the IntelliSense popup, making it quick and easy for the developer to choose the class member to call.
How to Fix Violations
To fix a violation of this rule, insert the ‘this.’ prefix before the call to the class member.

Regarding to C++, when using templates it's sometimes necessary to use this to help compiler with name resolution:
template <typename T>
class Base {
public:
void exit();
};
template <typename T>
class Derived : Base<T> {
public:
void foo() {
exit(); // calls external exit() or error
// so you should use this->exit() if that was your intent
}
};

The general rule should be: use "this" to avoid ambiguity, don't use this if it's obvious to what you refer.
For example, when progamming in Java, this.getSomeValue() is not needed, since all function calls are method calls on "this". On the other hand, this.myProperty might be useful if there are lots of local variables within your method, or if there are static member variables, and you want to make clear that you access an instance variable.
Of course, sometimes "this" is unavoidable, as in
void setX(int x){ this.x = x; }

In objective-c
...
prop = value; // just an assignment
...
and
...
self.prop = value; // !!! equivalent to method call [self setProp:value]
...
differ much - you must be aware of what and why you're doing.

It's frowned upon, almost all of the time in general use. I never use "this" like that.
People do it because they get Intellisense in their editor by typing "this" and then a "dot". You also see it around a lot of places when automatic code generators are doing the coding.
Now as to the question to why using "this" throughout your code is a bad idea. First off, it can be used as a crutch to cover up the lack of a good naming convention. For example, I consider this block of code to be a "coding horror":
class Fudge {
public decimal PoundsOfChocolate {get; set;}
Fudge (decimal PoundsOfChocoloate) {
this.PoundsOfChocolate = PoundsOfChocolate;
}
}
Yuck. Better to use an agreed upon naming convention:
class Fudge {
public decimal PoundsOfChocolate {get; set;}
Fudge (decimal poundsOfChocoloate) {
PoundsOfChocolate = poundsOfChocolate;
}
}
Why is this better? Well, in the trivial case like the above example, it doesn't matter all that much. Things get worse when your functions get longer, and you have private variables in complex functions which might collide with your members.
Also, if you pepper your code with "this" keywords, it becomes more difficult to read since there is more repetitive text. And it is just more verbose without adding semantics. IMO more verbosity without added semantics is bad. My two cents. Downvote all you want.
That isn't to say that "this" has no valid uses. Far from it. If you use it to resolve the difference between calling a base member and a member in the current object, then it has its place. It has its place in code generators as well. But as whiskey has taught me, overuse of anything leads to pain.

I agree with Dave. It is longer.
It is simply a matter of style, there is no other effect.

It's primarily used for constructors and initialization functions (and I prefer this style to various underscores):
MyClass(hisValue) { this->hisValue = hisValue; }
Using this style everywhere is just a syntax bloat reminiscent of Hungarian notation. If you keep functions reasonably short, local variables and function parameters are immediately recognizable to the reader of code. If declaration is not within screen, it can can be assumed then to be a class member - so 'this' notation doesn't add any useful information.

I always use this for a simple reason:
(Example in C# but won't make a difference)
Take for example a class like this:
class Foo {
private int count = 0;
public List<Int32> foos = new List<Int32>();
public int DoCounting() {
foreach (Int32 foo in foos) {
if (foo > 50) ++count;
}
return count;
}
}
Now another coder of your company has to add a function quickly, i.e. count another loop. He doesn't look at your code but simply adds his own due to the time critical request (or because it's 11:59am and he wants to make a break):
class Foo {
private int count = 0;
public List<Int32> foos = new List<Int32>();
public List<Int32> bars = new List<Int32>();
public int DoCounting() {
int count = bars.Count;
for (int i = 0; i < count; ++i) {
bars[i]++;
}
foreach (Int32 foo in foos) {
if (foo > 50) ++count;
}
return count;
}
}
Now what happens? And how easily could this be prevented by always using this?
Ofc the example is unrealistic but it happens easily in more complex classes and methods and causes hard to track bugs.

Using this makes codes more cleaner and readable. Also you have no option but to use in a situation where the parameter name is the same as a member variable. How do you distinguish the two?
class Test {
int a;
void doA(int a) {
this.a = a; //if you do a=a its gonna be a bug really hard to catch
}
}

I would suggest always using this unless the code would behave differently if you did not. It at least acts as syntactic sugar for the programmer/reader to indicate that the RHS is coming from the current class.
Also, in some languages (Perl being one), if you leave off the object reference, then the inheritance heirarchy is not used when resolving the RHS. e.g. if methodName is defined in the parent, then $this->methodName() will work, but methodName() will fail because only the current package is searched.

It is really useful in a constructor where code like
this.field = field;
becomes more readable. I would put in methods too! Coloring of this doesn't hurt either.

Related

Generic "identifier" pattern in C#

CUrrently in the process of finally learning C#. But after using C++ and python this is one thing that keeps striking me while writing C#.
C# doesn't have a similar thing to typedef in C++. (Or at least htat's true according to various posts here an other googling results.
Now the first use to "type alias" I can understand (though from experience disagree with - but that's something I can learn to accept).
However there is a different use I've gotten used to a lot, especially after using python for years:
The "Generic" pattern. Where I actually don't care about the type (and say I only care that it can be compared to each other). Now of course a generic class can "do" this, but quite often that is overkill: especially since classes typically have many of those, and they are of little importance to people who USE the class.
An example, say I have a dictionary, which binds "values" to certain "identifiers":
System.Collections.Generics.Dictionary<string, double>
Would be a logical start. However say in the future, when having a clearer picture of the whole application, I wish to change it up. I notice that for calculations I would actually need decimal values instead of floating point - (or maybe even bignums instead of floating points). I'd have to go over my whole code changing this.
Similar to the identifier: strings are "easy" but maybe in the future I don't really want to use such bloated structures. Rather I use something that "can be converted from strings and is unique enough" in my class
Or, hey, in a different future I might wish to not use the generic dictionary: rather I implement a custom one for this class specific.
All these things would require me to change code at many different places. Potential bug-heavy, and thus a maintainer would choose not to change it due to maintenance problems.
In other languages I learned this was solved either by "don't caring" (python) - or by allowing a typedef. And always using that typedef, also in other classes.
What is the idiomatic way to do this in C#? Is it generally accepted to use long "lists" of generic variables in your class definition?
MyClass<A_KeyType, A_ValueType, B_KeyType, B_ValueType, ContainerType>
Seems awkward since not the user, but the maintainer of the class might often know better which to use?
As a very simplistic (silly) example
public class MyClass {
public MyClass() { }
private Systems.Collections.Generics.Dictionary<string, double> Points = new Systems.Collections.Generics.Dictionary<string, double>()
Public void AddPerson(string studentID, double val) {
Points.Add(studentID, val)
}
}
getters, maybe changers etc would all have to explicitly refer to Systems.Collections.Generics.Dictionary<string, double>, even though maybe in the future a studentID would be a simple numeric value or something else. Also the code "using" this, which "gets" the student ID needs to understand it is a string.
In C++ I would parametrize the student type "under" the my class as:
public class MyClass {
typedef string StudentIDType
...
Then I would use that explicit type MyClass.StudentIDType in all situations.
C# doesn't have a similar thing to typedef in C++.
Typedef in C defines a new type. C# has type aliases:
using Frob = System.Collections.Dictionary<System.String, System.String>;
...
Frob f = new Frob();
But these are per file. The named alias is not a member of any namespace or type.
And C# of course allows you to define new types by wrapping old ones:
struct MyOpaqueIdentifier
{
private int id;
public MyOpaqueIdentifier(int id) { this.id = id; }
... now define equality, conversions, etc ...
}
However say in the future, when having a clearer picture of the whole application, I wish to change it up
This is the premature generality error, also known as YAGNI: You Ain't Gonna Need It. There are infinite ways to design programs to be more general, most of which you will never need. The right way to do it is to think hard about what kinds of generalities you're going to need up front, and design them in from the beginning.
Also, remember that Visual Studio has powerful refactoring tools.
What is the idiomatic way to do this in C#? Is it generally accepted to use long "lists" of generic variables in your class definition?
C# lets you express generality in several ways:
base classes -- I can accept anything derived from this class.
interfaces -- I can accept anything that implements this interface.
generics -- the type is parameterized by n other types
generic covariance and contravariance -- a sequence of turtles may be used where a sequence of animals is expected
generic constraints -- a type argument is constrained to a base type, interface, etc.
delegates -- needed functionality that consists of a single method (example: compare two Ts for equality) can be passed in as a delegate to that function, rather than requiring an interface, base type, etc.
It sounds to me like you are considering abusing generics; one of the other approaches is typically used.
Try something like this:
class Program
{
static void Main(string[] args)
{
var obj = new Class1<int, string>();
obj.Dictionary.Add(1, "hello");
}
}
class Class1<Tkey, Tvalue>
{
public Dictionary<Tkey, Tvalue> Dictionary { get; set; }
}
If you want Python way, then use Dictionary<string, object>
You will sacrifice performance and may run into a lot of runtime issues at the cost of minimizing code changes.
I really don't see any value in this. The maintainer still has to go to all the places where you have used float and replace all variable and inputs. You are kinda missing the point of using a strongly typed compiled language.
Your best bet is to create a generic class that wraps your functionality
class MyClass<T>
{
Dictionary<string, T> innerDict;
}
You seem to have a fundamental misunderstanding of generics in C#. They are not meant to allow for easy refactoring the way your C++ with typedef seems prepared for future maintainers to switch the type out. Such a usage seems wrong and, while I don't code in C++, I assume this is less used as a "generic" and more of an "anonymous class" definition. That is to say, you are actually defining a pseudoclass of type StudentIDType whose only property is a string value that you can access directly via the "alias". There are such a thing as anonymous classes in C# (see closures) but they are defined as the input for some function. Rather, the C# method of handling the above situation is to properly reify the pseudoclass to be an explicitly declared class. Such an implementation would look like this:
public class MyClass {
// DO NOT EVER DO THIS
// classes should not contain public classes this is merely the smallest possible example
public class StudentPoints {
public string StudentId { get; set; }
public double PointsValue { get; set; }
}
private IEnumerable<StudentPoints> StudentPointsList = new List<StudentPoints>();
public void AddPerson(StudentPoints studentPoints) {
this.StudentPointsList.Add(studentPoints);
}
}
However, there is an obvious problem with the above which should illustrate to you why the anonymous class is a bad idea. The first is that you've abandoned Dictionary for a simpler List/IEnumerable. This means you can't access values by key without "searching the list" (that is you no longer have a hash table implementation). The second is that you are still bound to change types when refactoring. Unless you can implicitly convert from one to another of the types you switch out then you will still have to change the constructors you use in your code to create StudentPoints. It is unavoidably true that changing the type of something will require code changes for most if not all references to that object. This is exactly what the refactoring tools in Visual Studio are built to help with. However, there is a pattern that you can use that is C# and would allow you to at least "reduce" the pain of the transition so that you don't have to find every instance in the code base before it will compile again. That pattern looks like this and utilizes overloads + the [Obsolete] parameter to indicate you are moving away from the old type and moving to the new:
public class MyClass {
private Dictionary<int, double> StudentPoints = new Dictionary<int, double>(); //was string, double
[Obsolete] // unfixed code will call this
public void AddPerson(string studentId, double val) {
int studentIdInt;
if (Int32.TryParse(studentId, out studentIdInt) {
this.AddPerson(studentIdInt, val);
return;
}
throw new ArgumentException(nameof(studentId), "string not convertable to int");
}
public void AddPerson(int studentId, double val) {
this.StudentList.Add(studentId, val);
}
}
Now the compiler will warn you instead of erroring when you pass a string instead. Issues here are that you may now get a runtime error for any string that isn't convertable to an int, something that would be a compile time error otherwise. Additionally this pattern (overload+obsolete attribute) could be used even with the first "reified" class as a constructor but my point is that you don't need to reify the class (in fact its unhelpful). Instead you should understand that yes, generics should declare their types as specifically as possible and yes, there are refactoring patterns that exist so that you can compile your code relatively quickly after changing the type for a generic but it comes with the trade of turning compile time errors into runtime errors. Hope that helps.

C# Encapsulation (OOP) [duplicate]

What's the advantage of using getters and setters - that only get and set - instead of simply using public fields for those variables?
If getters and setters are ever doing more than just the simple get/set, I can figure this one out very quickly, but I'm not 100% clear on how:
public String foo;
is any worse than:
private String foo;
public void setFoo(String foo) { this.foo = foo; }
public String getFoo() { return foo; }
Whereas the former takes a lot less boilerplate code.
There are actually many good reasons to consider using accessors rather than directly exposing fields of a class - beyond just the argument of encapsulation and making future changes easier.
Here are the some of the reasons I am aware of:
Encapsulation of behavior associated with getting or setting the property - this allows additional functionality (like validation) to be added more easily later.
Hiding the internal representation of the property while exposing a property using an alternative representation.
Insulating your public interface from change - allowing the public interface to remain constant while the implementation changes without affecting existing consumers.
Controlling the lifetime and memory management (disposal) semantics of the property - particularly important in non-managed memory environments (like C++ or Objective-C).
Providing a debugging interception point for when a property changes at runtime - debugging when and where a property changed to a particular value can be quite difficult without this in some languages.
Improved interoperability with libraries that are designed to operate against property getter/setters - Mocking, Serialization, and WPF come to mind.
Allowing inheritors to change the semantics of how the property behaves and is exposed by overriding the getter/setter methods.
Allowing the getter/setter to be passed around as lambda expressions rather than values.
Getters and setters can allow different access levels - for example the get may be public, but the set could be protected.
Because 2 weeks (months, years) from now when you realize that your setter needs to do more than just set the value, you'll also realize that the property has been used directly in 238 other classes :-)
A public field is not worse than a getter/setter pair that does nothing except returning the field and assigning to it. First, it's clear that (in most languages) there is no functional difference. Any difference must be in other factors, like maintainability or readability.
An oft-mentioned advantage of getter/setter pairs, isn't. There's this claim that you can change the implementation and your clients don't have to be recompiled. Supposedly, setters let you add functionality like validation later on and your clients don't even need to know about it. However, adding validation to a setter is a change to its preconditions, a violation of the previous contract, which was, quite simply, "you can put anything in here, and you can get that same thing later from the getter".
So, now that you broke the contract, changing every file in the codebase is something you should want to do, not avoid. If you avoid it you're making the assumption that all the code assumed the contract for those methods was different.
If that should not have been the contract, then the interface was allowing clients to put the object in invalid states. That's the exact opposite of encapsulation If that field could not really be set to anything from the start, why wasn't the validation there from the start?
This same argument applies to other supposed advantages of these pass-through getter/setter pairs: if you later decide to change the value being set, you're breaking the contract. If you override the default functionality in a derived class, in a way beyond a few harmless modifications (like logging or other non-observable behaviour), you're breaking the contract of the base class. That is a violation of the Liskov Substitutability Principle, which is seen as one of the tenets of OO.
If a class has these dumb getters and setters for every field, then it is a class that has no invariants whatsoever, no contract. Is that really object-oriented design? If all the class has is those getters and setters, it's just a dumb data holder, and dumb data holders should look like dumb data holders:
class Foo {
public:
int DaysLeft;
int ContestantNumber;
};
Adding pass-through getter/setter pairs to such a class adds no value. Other classes should provide meaningful operations, not just operations that fields already provide. That's how you can define and maintain useful invariants.
Client: "What can I do with an object of this class?"
Designer: "You can read and write several variables."
Client: "Oh... cool, I guess?"
There are reasons to use getters and setters, but if those reasons don't exist, making getter/setter pairs in the name of false encapsulation gods is not a good thing. Valid reasons to make getters or setters include the things often mentioned as the potential changes you can make later, like validation or different internal representations. Or maybe the value should be readable by clients but not writable (for example, reading the size of a dictionary), so a simple getter is a nice choice. But those reasons should be there when you make the choice, and not just as a potential thing you may want later. This is an instance of YAGNI (You Ain't Gonna Need It).
Lots of people talk about the advantages of getters and setters but I want to play devil's advocate. Right now I'm debugging a very large program where the programmers decided to make everything getters and setters. That might seem nice, but its a reverse-engineering nightmare.
Say you're looking through hundreds of lines of code and you come across this:
person.name = "Joe";
It's a beautifully simply piece of code until you realize its a setter. Now, you follow that setter and find that it also sets person.firstName, person.lastName, person.isHuman, person.hasReallyCommonFirstName, and calls person.update(), which sends a query out to the database, etc. Oh, that's where your memory leak was occurring.
Understanding a local piece of code at first glance is an important property of good readability that getters and setters tend to break. That is why I try to avoid them when I can, and minimize what they do when I use them.
In a pure object-oriented world getters and setters is a terrible anti-pattern. Read this article: Getters/Setters. Evil. Period. In a nutshell, they encourage programmers to think about objects as of data structures, and this type of thinking is pure procedural (like in COBOL or C). In an object-oriented language there are no data structures, but only objects that expose behavior (not attributes/properties!)
You may find more about them in Section 3.5 of Elegant Objects (my book about object-oriented programming).
There are many reasons. My favorite one is when you need to change the behavior or regulate what you can set on a variable. For instance, lets say you had a setSpeed(int speed) method. But you want that you can only set a maximum speed of 100. You would do something like:
public void setSpeed(int speed) {
if ( speed > 100 ) {
this.speed = 100;
} else {
this.speed = speed;
}
}
Now what if EVERYWHERE in your code you were using the public field and then you realized you need the above requirement? Have fun hunting down every usage of the public field instead of just modifying your setter.
My 2 cents :)
One advantage of accessors and mutators is that you can perform validation.
For example, if foo was public, I could easily set it to null and then someone else could try to call a method on the object. But it's not there anymore! With a setFoo method, I could ensure that foo was never set to null.
Accessors and mutators also allow for encapsulation - if you aren't supposed to see the value once its set (perhaps it's set in the constructor and then used by methods, but never supposed to be changed), it will never been seen by anyone. But if you can allow other classes to see or change it, you can provide the proper accessor and/or mutator.
Thanks, that really clarified my thinking. Now here is (almost) 10 (almost) good reasons NOT to use getters and setters:
When you realize you need to do more than just set and get the value, you can just make the field private, which will instantly tell you where you've directly accessed it.
Any validation you perform in there can only be context free, which validation rarely is in practice.
You can change the value being set - this is an absolute nightmare when the caller passes you a value that they [shock horror] want you to store AS IS.
You can hide the internal representation - fantastic, so you're making sure that all these operations are symmetrical right?
You've insulated your public interface from changes under the sheets - if you were designing an interface and weren't sure whether direct access to something was OK, then you should have kept designing.
Some libraries expect this, but not many - reflection, serialization, mock objects all work just fine with public fields.
Inheriting this class, you can override default functionality - in other words you can REALLY confuse callers by not only hiding the implementation but making it inconsistent.
The last three I'm just leaving (N/A or D/C)...
Depends on your language. You've tagged this "object-oriented" rather than "Java", so I'd like to point out that ChssPly76's answer is language-dependent. In Python, for instance, there is no reason to use getters and setters. If you need to change the behavior, you can use a property, which wraps a getter and setter around basic attribute access. Something like this:
class Simple(object):
def _get_value(self):
return self._value -1
def _set_value(self, new_value):
self._value = new_value + 1
def _del_value(self):
self.old_values.append(self._value)
del self._value
value = property(_get_value, _set_value, _del_value)
Well i just want to add that even if sometimes they are necessary for the encapsulation and security of your variables/objects, if we want to code a real Object Oriented Program, then we need to STOP OVERUSING THE ACCESSORS, cause sometimes we depend a lot on them when is not really necessary and that makes almost the same as if we put the variables public.
EDIT: I answered this question because there are a bunch of people learning programming asking this, and most of the answers are very technically competent, but they're not as easy to understand if you're a newbie. We were all newbies, so I thought I'd try my hand at a more newbie friendly answer.
The two main ones are polymorphism, and validation. Even if it's just a stupid data structure.
Let's say we have this simple class:
public class Bottle {
public int amountOfWaterMl;
public int capacityMl;
}
A very simple class that holds how much liquid is in it, and what its capacity is (in milliliters).
What happens when I do:
Bottle bot = new Bottle();
bot.amountOfWaterMl = 1500;
bot.capacityMl = 1000;
Well, you wouldn't expect that to work, right?
You want there to be some kind of sanity check. And worse, what if I never specified the maximum capacity? Oh dear, we have a problem.
But there's another problem too. What if bottles were just one type of container? What if we had several containers, all with capacities and amounts of liquid filled? If we could just make an interface, we could let the rest of our program accept that interface, and bottles, jerrycans and all sorts of stuff would just work interchangably. Wouldn't that be better? Since interfaces demand methods, this is also a good thing.
We'd end up with something like:
public interface LiquidContainer {
public int getAmountMl();
public void setAmountMl(int amountMl);
public int getCapacityMl();
}
Great! And now we just change Bottle to this:
public class Bottle implements LiquidContainer {
private int capacityMl;
private int amountFilledMl;
public Bottle(int capacityMl, int amountFilledMl) {
this.capacityMl = capacityMl;
this.amountFilledMl = amountFilledMl;
checkNotOverFlow();
}
public int getAmountMl() {
return amountFilledMl;
}
public void setAmountMl(int amountMl) {
this.amountFilled = amountMl;
checkNotOverFlow();
}
public int getCapacityMl() {
return capacityMl;
}
private void checkNotOverFlow() {
if(amountOfWaterMl > capacityMl) {
throw new BottleOverflowException();
}
}
I'll leave the definition of the BottleOverflowException as an exercise to the reader.
Now notice how much more robust this is. We can deal with any type of container in our code now by accepting LiquidContainer instead of Bottle. And how these bottles deal with this sort of stuff can all differ. You can have bottles that write their state to disk when it changes, or bottles that save on SQL databases or GNU knows what else.
And all these can have different ways to handle various whoopsies. The Bottle just checks and if it's overflowing it throws a RuntimeException. But that might be the wrong thing to do.
(There is a useful discussion to be had about error handling, but I'm keeping it very simple here on purpose. People in comments will likely point out the flaws of this simplistic approach. ;) )
And yes, it seems like we go from a very simple idea to getting much better answers quickly.
Please note also that you can't change the capacity of a bottle. It's now set in stone. You could do this with an int by declaring it final. But if this was a list, you could empty it, add new things to it, and so on. You can't limit the access to touching the innards.
There's also the third thing that not everyone has addressed: getters and setters use method calls. That means that they look like normal methods everywhere else does. Instead of having weird specific syntax for DTOs and stuff, you have the same thing everywhere.
I know it's a bit late, but I think there are some people who are interested in performance.
I've done a little performance test. I wrote a class "NumberHolder" which, well, holds an Integer. You can either read that Integer by using the getter method
anInstance.getNumber() or by directly accessing the number by using anInstance.number. My programm reads the number 1,000,000,000 times, via both ways. That process is repeated five times and the time is printed. I've got the following result:
Time 1: 953ms, Time 2: 741ms
Time 1: 655ms, Time 2: 743ms
Time 1: 656ms, Time 2: 634ms
Time 1: 637ms, Time 2: 629ms
Time 1: 633ms, Time 2: 625ms
(Time 1 is the direct way, Time 2 is the getter)
You see, the getter is (almost) always a bit faster. Then I tried with different numbers of cycles. Instead of 1 million, I used 10 million and 0.1 million.
The results:
10 million cycles:
Time 1: 6382ms, Time 2: 6351ms
Time 1: 6363ms, Time 2: 6351ms
Time 1: 6350ms, Time 2: 6363ms
Time 1: 6353ms, Time 2: 6357ms
Time 1: 6348ms, Time 2: 6354ms
With 10 million cycles, the times are almost the same.
Here are 100 thousand (0.1 million) cycles:
Time 1: 77ms, Time 2: 73ms
Time 1: 94ms, Time 2: 65ms
Time 1: 67ms, Time 2: 63ms
Time 1: 65ms, Time 2: 65ms
Time 1: 66ms, Time 2: 63ms
Also with different amounts of cycles, the getter is a little bit faster than the regular way. I hope this helped you.
Don't use getters setters unless needed for your current delivery I.e. Don't think too much about what would happen in the future, if any thing to be changed its a change request in most of the production applications, systems.
Think simple, easy, add complexity when needed.
I would not take advantage of ignorance of business owners of deep technical know how just because I think it's correct or I like the approach.
I have massive system written without getters setters only with access modifiers and some methods to validate n perform biz logic. If you absolutely needed the. Use anything.
We use getters and setters:
for reusability
to perform validation in later stages of programming
Getter and setter methods are public interfaces to access private class members.
Encapsulation mantra
The encapsulation mantra is to make fields private and methods public.
Getter Methods: We can get access to private variables.
Setter Methods: We can modify private fields.
Even though the getter and setter methods do not add new functionality, we can change our mind come back later to make that method
better;
safer; and
faster.
Anywhere a value can be used, a method that returns that value can be added. Instead of:
int x = 1000 - 500
use
int x = 1000 - class_name.getValue();
In layman's terms
Suppose we need to store the details of this Person. This Person has the fields name, age and sex. Doing this involves creating methods for name, age and sex. Now if we need create another person, it becomes necessary to create the methods for name, age, sex all over again.
Instead of doing this, we can create a bean class(Person) with getter and setter methods. So tomorrow we can just create objects of this Bean class(Person class) whenever we need to add a new person (see the figure). Thus we are reusing the fields and methods of bean class, which is much better.
I spent quite a while thinking this over for the Java case, and I believe the real reasons are:
Code to the interface, not the implementation
Interfaces only specify methods, not fields
In other words, the only way you can specify a field in an interface is by providing a method for writing a new value and a method for reading the current value.
Those methods are the infamous getter and setter....
It can be useful for lazy-loading. Say the object in question is stored in a database, and you don't want to go get it unless you need it. If the object is retrieved by a getter, then the internal object can be null until somebody asks for it, then you can go get it on the first call to the getter.
I had a base page class in a project that was handed to me that was loading some data from a couple different web service calls, but the data in those web service calls wasn't always used in all child pages. Web services, for all of the benefits, pioneer new definitions of "slow", so you don't want to make a web service call if you don't have to.
I moved from public fields to getters, and now the getters check the cache, and if it's not there call the web service. So with a little wrapping, a lot of web service calls were prevented.
So the getter saves me from trying to figure out, on each child page, what I will need. If I need it, I call the getter, and it goes to find it for me if I don't already have it.
protected YourType _yourName = null;
public YourType YourName{
get
{
if (_yourName == null)
{
_yourName = new YourType();
return _yourName;
}
}
}
One aspect I missed in the answers so far, the access specification:
for members you have only one access specification for both setting and getting
for setters and getters you can fine tune it and define it separately
In languages which don't support "properties" (C++, Java) or require recompilation of clients when changing fields to properties (C#), using get/set methods is easier to modify. For example, adding validation logic to a setFoo method will not require changing the public interface of a class.
In languages which support "real" properties (Python, Ruby, maybe Smalltalk?) there is no point to get/set methods.
One of the basic principals of OO design: Encapsulation!
It gives you many benefits, one of which being that you can change the implementation of the getter/setter behind the scenes but any consumer of that value will continue to work as long as the data type remains the same.
You should use getters and setters when:
You're dealing with something that is conceptually an attribute, but:
Your language doesn't have properties (or some similar mechanism, like Tcl's variable traces), or
Your language's property support isn't sufficient for this use case, or
Your language's (or sometimes your framework's) idiomatic conventions encourage getters or setters for this use case.
So this is very rarely a general OO question; it's a language-specific question, with different answers for different languages (and different use cases).
From an OO theory point of view, getters and setters are useless. The interface of your class is what it does, not what its state is. (If not, you've written the wrong class.) In very simple cases, where what a class does is just, e.g., represent a point in rectangular coordinates,* the attributes are part of the interface; getters and setters just cloud that. But in anything but very simple cases, neither the attributes nor getters and setters are part of the interface.
Put another way: If you believe that consumers of your class shouldn't even know that you have a spam attribute, much less be able to change it willy-nilly, then giving them a set_spam method is the last thing you want to do.
* Even for that simple class, you may not necessarily want to allow setting the x and y values. If this is really a class, shouldn't it have methods like translate, rotate, etc.? If it's only a class because your language doesn't have records/structs/named tuples, then this isn't really a question of OO…
But nobody is ever doing general OO design. They're doing design, and implementation, in a specific language. And in some languages, getters and setters are far from useless.
If your language doesn't have properties, then the only way to represent something that's conceptually an attribute, but is actually computed, or validated, etc., is through getters and setters.
Even if your language does have properties, there may be cases where they're insufficient or inappropriate. For example, if you want to allow subclasses to control the semantics of an attribute, in languages without dynamic access, a subclass can't substitute a computed property for an attribute.
As for the "what if I want to change my implementation later?" question (which is repeated multiple times in different wording in both the OP's question and the accepted answer): If it really is a pure implementation change, and you started with an attribute, you can change it to a property without affecting the interface. Unless, of course, your language doesn't support that. So this is really just the same case again.
Also, it's important to follow the idioms of the language (or framework) you're using. If you write beautiful Ruby-style code in C#, any experienced C# developer other than you is going to have trouble reading it, and that's bad. Some languages have stronger cultures around their conventions than others.—and it may not be a coincidence that Java and Python, which are on opposite ends of the spectrum for how idiomatic getters are, happen to have two of the strongest cultures.
Beyond human readers, there will be libraries and tools that expect you to follow the conventions, and make your life harder if you don't. Hooking Interface Builder widgets to anything but ObjC properties, or using certain Java mocking libraries without getters, is just making your life more difficult. If the tools are important to you, don't fight them.
From a object orientation design standpoint both alternatives can be damaging to the maintenance of the code by weakening the encapsulation of the classes. For a discussion you can look into this excellent article: http://typicalprogrammer.com/?p=23
Code evolves. private is great for when you need data member protection. Eventually all classes should be sort of "miniprograms" that have a well-defined interface that you can't just screw with the internals of.
That said, software development isn't about setting down that final version of the class as if you're pressing some cast iron statue on the first try. While you're working with it, code is more like clay. It evolves as you develop it and learn more about the problem domain you are solving. During development classes may interact with each other than they should (dependency you plan to factor out), merge together, or split apart. So I think the debate boils down to people not wanting to religiously write
int getVar() const { return var ; }
So you have:
doSomething( obj->getVar() ) ;
Instead of
doSomething( obj->var ) ;
Not only is getVar() visually noisy, it gives this illusion that gettingVar() is somehow a more complex process than it really is. How you (as the class writer) regard the sanctity of var is particularly confusing to a user of your class if it has a passthru setter -- then it looks like you're putting up these gates to "protect" something you insist is valuable, (the sanctity of var) but yet even you concede var's protection isn't worth much by the ability for anyone to just come in and set var to whatever value they want, without you even peeking at what they are doing.
So I program as follows (assuming an "agile" type approach -- ie when I write code not knowing exactly what it will be doing/don't have time or experience to plan an elaborate waterfall style interface set):
1) Start with all public members for basic objects with data and behavior. This is why in all my C++ "example" code you'll notice me using struct instead of class everywhere.
2) When an object's internal behavior for a data member becomes complex enough, (for example, it likes to keep an internal std::list in some kind of order), accessor type functions are written. Because I'm programming by myself, I don't always set the member private right away, but somewhere down the evolution of the class the member will be "promoted" to either protected or private.
3) Classes that are fully fleshed out and have strict rules about their internals (ie they know exactly what they are doing, and you are not to "fuck" (technical term) with its internals) are given the class designation, default private members, and only a select few members are allowed to be public.
I find this approach allows me to avoid sitting there and religiously writing getter/setters when a lot of data members get migrated out, shifted around, etc. during the early stages of a class's evolution.
There is a good reason to consider using accessors is there is no property inheritance. See next example:
public class TestPropertyOverride {
public static class A {
public int i = 0;
public void add() {
i++;
}
public int getI() {
return i;
}
}
public static class B extends A {
public int i = 2;
#Override
public void add() {
i = i + 2;
}
#Override
public int getI() {
return i;
}
}
public static void main(String[] args) {
A a = new B();
System.out.println(a.i);
a.add();
System.out.println(a.i);
System.out.println(a.getI());
}
}
Output:
0
0
4
Getters and setters are used to implement two of the fundamental aspects of Object Oriented Programming which are:
Abstraction
Encapsulation
Suppose we have an Employee class:
package com.highmark.productConfig.types;
public class Employee {
private String firstName;
private String middleName;
private String lastName;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getMiddleName() {
return middleName;
}
public void setMiddleName(String middleName) {
this.middleName = middleName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getFullName(){
return this.getFirstName() + this.getMiddleName() + this.getLastName();
}
}
Here the implementation details of Full Name is hidden from the user and is not accessible directly to the user, unlike a public attribute.
There is a difference between DataStructure and Object.
Datastructure should expose its innards and not behavior.
An Object should not expose its innards but it should expose its behavior, which is also known as the Law of Demeter
Mostly DTOs are considered more of a datastructure and not Object. They should only expose their data and not behavior. Having Setter/Getter in DataStructure will expose behavior instead of data inside it. This further increases the chance of violation of Law of Demeter.
Uncle Bob in his book Clean code explained the Law of Demeter.
There is a well-known heuristic called the Law of Demeter that says a
module should not know about the innards of the objects it
manipulates. As we saw in the last section, objects hide their data
and expose operations. This means that an object should not expose its
internal structure through accessors because to do so is to expose,
rather than to hide, its internal structure.
More precisely, the Law of Demeter says that a method f of a class C
should only call the methods of these:
C
An object created by f
An object passed as an argument to f
An object held in an instance variable of C
The method should not invoke methods on objects that are returned by any of the allowed functions.
In other words, talk to friends, not to strangers.
So according this, example of LoD violation is:
final String outputDir = ctxt.getOptions().getScratchDir().getAbsolutePath();
Here, the function should call the method of its immediate friend which is ctxt here, It should not call the method of its immediate friend's friend. but this rule doesn't apply to data structure. so here if ctxt, option, scratchDir are datastructure then why to wrap their internal data with some behavior and doing a violation of LoD.
Instead, we can do something like this.
final String outputDir = ctxt.options.scratchDir.absolutePath;
This fulfills our needs and doesn't even violate LoD.
Inspired by Clean Code by Robert C. Martin(Uncle Bob)
If you don't require any validations and not even need to maintain state i.e. one property depends on another so we need to maintain the state when one is change. You can keep it simple by making field public and not using getter and setters.
I think OOPs complicates things as the program grows it becomes nightmare for developer to scale.
A simple example; we generate c++ headers from xml. The header contains simple field which does not require any validations. But still as in OOPS accessor are fashion we generates them as following.
const Filed& getfield() const
Field& getField()
void setfield(const Field& field){...}
which is very verbose and is not required. a simple
struct
{
Field field;
};
is enough and readable.
Functional programming don't have the concept of data hiding they even don't require it as they do not mutate the data.
Additionally, this is to "future-proof" your class. In particular, changing from a field to a property is an ABI break, so if you do later decide that you need more logic than just "set/get the field", then you need to break ABI, which of course creates problems for anything else already compiled against your class.
One other use (in languages that support properties) is that setters and getters can imply that an operation is non-trivial. Typically, you want to avoid doing anything that's computationally expensive in a property.
One relatively modern advantage of getters/setters is that is makes it easier to browse code in tagged (indexed) code editors. E.g. If you want to see who sets a member, you can open the call hierarchy of the setter.
On the other hand, if the member is public, the tools don't make it possible to filter read/write access to the member. So you have to trudge though all uses of the member.
Getters and setters coming from data hiding. Data Hiding means We
are hiding data from outsiders or outside person/thing cannot access
our data.This is a useful feature in OOP.
As a example:
If you create a public variable, you can access that variable and change value in anywhere(any class). But if you create as private that variable cannot see/access in any class except declared class.
public and private are access modifiers.
So how can we access that variable outside:
This is the place getters and setters coming from. You can declare variable as private then you can implement getter and setter for that variable.
Example(Java):
private String name;
public String getName(){
return this.name;
}
public void setName(String name){
this.name= name;
}
Advantage:
When anyone want to access or change/set value to balance variable, he/she must have permision.
//assume we have person1 object
//to give permission to check balance
person1.getName()
//to give permission to set balance
person1.setName()
You can set value in constructor also but when later on when you want
to update/change value, you have to implement setter method.

Pros and Cons of implementing Properties in Java

In C# there exists a type of member that is called a Property. This allows you to easily and simply define a private field and provide simple or complex getters and setters while saving space by not having to define whole methods. Java does not have anything like this, and from what I can see, the general consensus has been to suck it up and define complete getter and setter methods for private variables.
Currently, I have been toying with the following class:
public class Property<T> {
private T value = null;
public Property(){}
public Property(T initialValue){
value = initialValue;
}
public T get(){
return value;
}
public void set(T newValue){
value = newValue;
}
}
With this implementation, you can define simple properties that only require getters and setters:
final Property<String> name = new Property<>("Dog");
Or more advanced options like the one that MSDN provides for C#:
...
public double seconds;
public final Property<Double> Hours = new Property<Double>(){
#Override
public Double get() {
return seconds/3600;
}
#Override
public void set(Double newValue) {
seconds = newValue * 3600;
}
};
...
What would be the pros and cons of this solution?
The pros are largely obvious. I'll point out some that make it better than C#'s properties:
The backing field is tucked away so that you don't accidentally use it instead of the property. (but the downside is that you can't easily choose to use the backing field if you want)
Unlike C#'s auto-properties, you can choose to override only the get or set method, not both, e.g.
public Property<List<String>> MyList = new Property<List<String>>(){
#Override
public List<String> get() {
if (value == null)
value = new ArrayList<String>();
return value;
}
// set still works
};
There are cons, however:
It is not part of the Java language, or any common libraries, so it can be confusing for people who read your code (including yourself in the future).
You cannot change the visibility of the get and set methods: if the Property<T> can be accessed, you can both get and set the value.
If you don't make your Property field final, anyone that can access it can change it to their own Property implementation. This could be useful, but mostly would be a pain.
(this is a con shared with C#'s properties) You can't change the arguments that are passed to the get and set methods. E.g. you can't have a Property<MyType> with both a set(MyType) and a set(CompatibleType) method (unless you extend Property).
Using generics pervasively means that at run-time, (thanks to type erasure) you're using Object pervasively. This boxing/unboxing might make for a slight performance decrease (not noticeable in most apps) if you use primitives (e.g. using double vs Property<Double>).
By the way, Scala is a language that runs on the JVM that includes properties as a native feature, and interoperates with Java's version of properties (getters/setters). You might want to look into that, since basically someone else already hacked the Java language for you. =)
All in all, I'd say you shouldn't try to make Java have properties. When in Rome, do as the Romans do. If you don't like how the Romans do it, move down the street (Scala) or across the country (C#).
So the complete syntax, say for name, would now be:
theObject.name.set("new name");
The point is, how are you accessing that name object? Is it public / protected Then it could be overridden. Is it private? Then you can't change it outside the class anyways.
The solution you've proposed only works if you already have access to the object, at which point you don't need the solution.
The pros of this solution (your anonymous inner class) is that, if you are not needing to implement this anywhere else, it saves you from writing an entire extra class just for this one situation.
The con of this solution is that later you may want to implement it elsewhere, and then you'd want to refactor your code to extract the implementation of Property<Double> into its own class to avoid repeating yourself.
I'd say, if you're pretty sure you're not going to need this implementation anywhere else (I'm guessing you won't), just go ahead with the later solution of an anonymous inner class. It's a good one.

In C#, is there a way to enforce use of "this/base" qualification in instance members?

Sometimes it can be confusing reading code in instance members that refers to other instance members of the same class (or a base class):
public void MyMethod()
{
Where = did + AllTheseWeirdThings(GetDeclared()); // ?
}
Having a coding standard something like "prefix all private/protected members with "_" doesn't help, because instance members can still refer to public members.
It would be much better to read this:
public void MyMethod()
{
this.Where = this.did + base.AllTheseWeirdThings(this.GetDeclared()); // ?
}
Is there a way to enforce this, either with compiler options, StyleCop, or something similar?
There's no compiler option that enforces your rule.
However, a cursory Google search brings up this StyleCop rule: http://www.thewayithink.co.uk/stylecop/sa1101.htm
ReSharper has a similar option.
In C# this and base are optional. The only time you need to use them (in this context) is if there is an ambiguity. There is no compiler switch to change this behaviour.
I'd also suggest not adding the StyleCop rule. It's generally better to only use this and base when you have to, for example in a constructor you might write:
this.foo = foo;
Enforcing usage of the "this" and "base" keywords won't make the code any better quality, or any more readable. If your code is so confusing that you can't figure out where members are defined I'd suggest refactoring it and making your class heirarchy simpler.

Are accessors (get and set functions) popular with C++ programmers?

I'm from the world of C# originally, and I'm learning C++. I've been wondering about get and set functions in C++. In C# usage of these are quite popular, and tools like Visual Studio promote usage by making them very easy and quick to implement. However, this doesn't seem to be the case in the C++ world.
Here's the C# 2.0 code:
public class Foo
{
private string bar;
public string Bar
{
get { return bar; }
set { bar = value; }
}
}
Or, in C# 3.0:
public class Foo { get; set; }
May people will say, well whats the point in that? Why not just create a public field and then make it a property later if you need to; honestly, I'm actually not sure. I just do it out of good practice because I've seen it done so many times.
Now because I'm so used to doing it, I feel like I should carry over the habit to my C++ code, but is this really necessary? I don't see it done as often as with C#.
Anyway, here's the C++ from what I gather:
class Foo
{
public:
std::string GetBar() const; // Thanks for the tip, #Daniel Earwicker.
void SetBar(std::string bar);
private:
std::string bar;
}
std::string Foo::GetBar() const
{
return bar;
}
void Foo::SetBar(std::string bar)
{
// Also, I always wonder if using 'this->' is good practice.
this->bar = bar;
}
Now, to me that seems like a whole lot of leg work; considering using Visual Studio's tools the C# implementation would take literally seconds to implement, and the C++ took me a lot longer to type - I feel its not worth the effort, especially when the alternative is 5 lines long:
class Foo
{
public:
std::string Bar;
}
From what I gather, these are the advantages:
You can change implementation details for the get and set functions, so instead of returning a private field you can return something more interesting.
You can remove a get/set later on and make it read/write only (but for a public facing interface, this seems, not good).
And the disadvantages:
Takes ages to type, is this really worth the effort? Generally speaking. In some cases, the advantages make it worth the effort, but I mean, speaking in terms of "good practice", is it?
Answer:
Why did I choose the answer with less votes? I was actually very close to choosing veefu's answer; however my personal opinion (which is apparently controversial), is that the answer over egged the pudding.
The answer I chose, on the other hand, seems to argue both sides; I think getters and setters are evil if used excessively (by that I mean, when it's not necessary and would break the business model), but why shouldn't we have a function called GetBalance()?
Surely this would be far more versatile than PrintBalance(); what if I wanted to show it to the user in another way than as the class wanted me to? Now, in some sense GetBalance() may not be relevant enough to argue that "getters and setters are good" because it doesn't (or maybe, shouldn't) have an accompanying setter, and speaking of which, a function called SetBalance(float f) could be bad (in my opinion) because it would imply to the implementer of the function that the account must be manipulated out side of the class, which is not a good thing.
I'd argue that providing accessors are more important in C++ than in C#.
C++ has no builtin support for properties. In C# you can change a public field to a property mostly without changing the user code. In C++ this is harder.
For less typing you can implement trivial setters/getters as inline methods:
class Foo
{
public:
const std::string& bar() const { return _bar; }
void bar(const std::string& bar) { _bar = bar; }
private:
std::string _bar;
};
And don't forget that getters and setters are somewhat evil.
At the risk of being argumentative, I'll back an opposing point of view I first encountered while reading "Holub on Patterns". It was a point of view that was very challenging, but made sense to me upon reflection:
Getters and Setters are Evil
Use of getters and setters is in opposition to the fundamentals of object oriented design: Data abstraction and encapsulation. Overuse of getters and setters will make your code less agile and maintainable in the long run. They ultimately expose the underlying implementation of your class, locking implementation details into the interface of the class.
Imagine your 'std::string Foo::bar' field needs to change from a std::string to another string class, that, say, is better optimized or supports a different character-set. You'll need to change the private data field, the getter, the setter, and all the client code of this class that calls these getters and setters.
Rather than design your classes to "provide data" and "receive data", design them to "perform operations" or "providide services". Ask yourself why you're writing a "GetBar" function. What are you doing with that data? Perhaps you're displaying that data on or doing some processing on it. Is this process better exposed as a method of Foo?
This not to say that getters and setters don't have their purpose. In C# I believe the fundamental reason for their use is to interface with the Visual Studio GUI-design IDE, but if you find yourself writing them in C++, it's probably best to take a step back, look at your design, and see if something is missing.
I'll try to mock-up an example to illustrate.
// A class that represents a user's bank account
class Account {
private:
int balance_; // in cents, lets say
public:
const int& GetBalance() { return balance_; }
void SetBalance(int b) { balance_ = b; }
};
class Deposit {
private:
int ammount_;
public:
const int& GetAmount() { return ammount_; }
void SetAmmount(int a) { _balance = a; }
};
void DoStuffWithAccount () {
Account a;
// print account balance
int balance = a.GetBalance();
std::cout << balance;
// deposit some money into account
Deposit d(10000);
a.SetBalance( a.GetBalance() + d.GetValue());
}
It doesn't take very long to see that this is very poorly designed.
Integers are an awful currency datatype
A Deposit should be a function of the Account
The getters and setters make it more difficult to fix the problems, since the client code DoStuffWithAccount is now bound to the data-type we used to implement the account balance.
So, lets make a pass on this code and see what we can improve
// A class that represents a user's bank account
class Account {
private:
float balance_;
public:
void Deposit(float b) { balance_ += b; }
void Withdraw(float w) { balance_ -= w; }
void DisplayDeposit(std::ostream &o) { o << balance_; }
};
void DoStuffWithAccount () {
Account a;
// print account balance
a.DisplayBalance(std::cout);
// deposit some money into account
float depositAmt = 1000.00;
a.Deposit(depositAmt);
a.DisplayBalance(std::cout);
}
The 'float' is a step in the right direction. Granted, you could have changed the internal type to 'float' and still supported the getter/setter idiom:
class Account {
private:
// int balance_; // old implementation
float balance_;
public:
// support the old interface
const int& GetBalance() { return (int) balance_; }
void SetBalance(int b) { balance_ = b; }
// provide a new interface for the float type
const float& GetBalance() { return balance_; } // not legal! how to expose getter for float as well as int??
void SetBalance(float b) { balance_ = b; }
};
but it doesn't take long to realize that the getter/setter arrangement is doubling your workload and complicating matters as you need to support both the code that used ints and the new code that will use floats. The Deposit function makes it a bit easier to expand the range of types for depositing.
An Account-like class is probably not the best example, since "getting" the account balance is a natural operation for an Account. The overall point, though, is that you must be careful with getters and setters. Do not get into the habit of writing getters and setters for every data-member. It is quite easy to expose and lock yourself into an implementation if you are not careful.
In your example:
class Foo
{
public:
const std::string GetBar(); // Should this be const, not sure?
You probably mean this:
std::string GetBar() const;
Putting the const at the end means "This function doesn't modify the Foo instance it is called on", so in a way it marks it as a pure getter.
Pure getters occur frequently in C++. An example in std::ostringstream is the str() function. The Standard library often follows a pattern of using the same function name for a pair of getter/setter functions - str being an example again.
As to whether it's too much work to type out, and is it worth it - that seems an odd question! If you need to give clients access to some information, provide a getter. If you don't, then don't.
There is no really strict convention on this, like there is in C# or Java. Many C++ programmers would just make the variable public an save themselves the trouble.
As other answers have said, you shouldn't often need set, and to some extent, get methods.
But if and when you do make them, there's no need to type more than necessary:
class Foo
{
public:
std::string Bar() const { return bar; }
void Bar(const std::string& bar) { this->bar = bar; }
private:
std::string bar;
};
Declaring the functions inline in the class saves typing, and hints to the compiler that you'd like the functions inlined. And it's not much more typing than the C# equivalents.
One thing to note is that I removed the get/set prefixes. Instead, we just have two Bar() overloads. That's fairly common in C++ (after all, if it doesn't take any arguments, we know it's the getter, and if it takes an argument, it's the setter. We don't need the name to tell us that), and it saves a bit more typing.
[edit] It seems I need to emphasize that setters need to validate parameters and enforce invariants, so they are usually not as simple as they are here. [/edit]
Not with all, because fo the extra typing. I tend to use them much more often now that Visual Assist gives me "encapsulate field".
The legwork is not more if you implement just the default setters / getters inline in the class declaration (which I tend to do - more complex setters move to the body, though).
Some notes:
constness:
Yes, the getter should be const. It is no use to make the return value const, though, if you return by value. For potentially complex return values you might want to use const & though:
std::string const & GetBar() const { return bar; }
Setter chaining: Many developers like to modify the setter as such:
Foo & SetBar(std::string const & bar) { this->bar = bar; return *this; }
Which allows calling multiple setters as such:
Foo foo;
foo.SetBar("Hello").SetBaz("world!");
It's not universally accepted as a good thing, though.
__declspec(property): Visual C++ provides this non-standard extension so that callers can use property syntax again. This increases legwork in the class a bit, but makes caller code much friendlier looking.
So, in conclusion, there's a little bit of more legwork, but a handful of decisions to make in C++. Typical ;)
I hardly ever use getters and setters in my own code. Veefu's answer looks good to me.
If you insist on having getters and/or setters, you can use macros to cut down on the boiler-plate.
#define GETTER(T,member) const T& Get##member() const { return member; }
#define SETTER(T,member) void Set##member(const T & value) { member = value; }
class Foo
{
public:
GETTER(std::string, bar)
SETTER(std::string, bar)
private:
std::string bar;
}
Getting and setting data members qua data members: Bad.
Getting and setting elements of the abstraction: Good.
The arguments against Get/Set in terms of API design in the banking example are spot on. Dont expose fields or properties if they will allow users to break your business rules.
However, once you have decided that you do need a field or property, always use a property.
The automatic properties in c# are very easy to use, and there are many scenarios (databinding, serialization, etc) that do not work with fields, but require properties.
If you are developing COM components then yes, it is very popular.
get and set are a pain inflicted upon people if you have to use them in any language.
Eiffel has it alot better where all that differs is the amount of information you have to provide to get the answer - a function with 0 parms is the same as accessing a member variable, and you can change freely between them.
When you control both sides of an interface the definition of the interface doesn't seem like such a big issue. However when you want to change implementation details and it inflicts the recompilation of client code as is the common case in C++ you wish to be able to minimise this as much as possible. As such pImpl and get/set would get used more in public APIs to avoid such damage.
Get and Set methods are useful if you have constraints in a variable value. For example, in many mathematical models there is a constraint to keep a certain float variable in the range [0,1]. In this case, Get, and Set (specially Set) can play a nice role:
class Foo{
public:
float bar() const { return _bar; }
void bar(const float& new_bar) { _bar = ((new_bar <= 1) && (new_bar >= 0))?new_bar:_bar; } // Keeps inside [0,1]
private:
float _bar; // must be in range [0,1]
};
Also, some properties must be recalculated before reading. In those cases, it may take a lot of unnecessary computing time to recalculate every cicle. So, a way to optimize it is to recalculate only when reading instead. To do so, overload the Get method in order to update the variable before reading it.
Otherwise, if there is no need to validade input values, or update output values, making the property public is not a crime and you can go along with it.
Yes , get and set are popular in the c++ world.
If you use C++/CLI as your varient of C++, then it has native property support in the language, so you can use
property String^ Name;
This is the same as
String Name{get;set;}
in C#. If you need more precise control over the get/set methods then you can use
property String^ Name
{
String^ get();
void set(String^ newName);
}
in the header and
String^ ClassName::Name::get()
{
return m_name;
}
void ClassName::Name::set(String^ newName)
{
m_name = newName;
}
in the .cpp file. I can't remember off hand, but I think you can have different access permissions for the get and set methods (public/private etc).
Colin
The compiler will emit set_ and get_ if you define a property, so it's really just save some typing.
This has been an interesting discussion. This is something from my favorite book "CLR via C#".
Here is what I quoted.
Personally, I don't like properties
and I wish that they were not
supported in the Microsoftm.NET
Framework and its programming
languages. The reason is because
properties look like fields but they
are methods. This has been known to
cause a phenomenal amount of
confu-sion. When a programmer sees
code that appears to be accessing a
field, there are many assumptions
that the programmer makes that may
not be true for a property. For
example,
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.
A property method can take a long time to execute; field access always
completes imme- diately. 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 synchro- nization 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
read- only 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.

Categories

Resources