views:

613

answers:

15

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?

+1  A: 

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.

Dave Markle
Doesn't explain why you shouldn't use this
David
It seems this is just opinion. How do you justfiy it?
Tomas Lycken
Using `this` makes it clear that you're accessing a member, rather than a local variable. It may add clarity. The only downside is that it adds extra characters to your code. Saying it's frowned upon is just false. There may be situations where it's not necessary, but that's not the same thing.
mcv
@mcv: Then again, it may not. A good, consistent naming convention makes it a lot easier in a lot less space to know what's what. Keeping your function scope tight also helps resolve ambiguity. If you're using "this" because you're naming different variables the same thing, you're making a mess.
Dave Markle
+1 for adding a thorough and well written response!
Benny Jobigan
+3  A: 

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.

finnw
This is one of the reasons why having a special naming convention for member vars is a good thing.
Andreas Magnusson
IME it isn't a problem often enough to justify making all my programs longer.
finnw
+13  A: 

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).

anon
Another example is when inheriting another class, and you override a method and want to be clear on which of `this.DoStuff()` and `base.DoStuff()` should be called.
Tomas Lycken
Neil's writing about C++ - it would be `this->DoStuff()` and `Base::DoStuff()`. And to be honest, I don't think `this->DoStuff()` adds clarity. I still need to check whether it's virtual for instance.
MSalters
A: 

I agree with Dave. It is longer.

It is simply a matter of style, there is no other effect.

KLE
A: 

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.

ima
Since it's obviously C++ (yep the -> gave you away), you should use MyClass(hisValue) : hisValue(hisValue) {}Besides you're lucky if you get all your team mates to strictly adhere to a maximum X lines per function quota. Easier then to enforce a single trailing underscore for each member variable.
Andreas Magnusson
Just random pseudocode, lack of type before hisValue should've given away it's not C++. And there should be no "maximum X lines per function", size of function should be largely determined - surprise! - by ability to "immediately recognize local variables and function parameters".
ima
And "easier than" part... I won't even comment on it. You should consider changing job, writing readable code and communicating it to your team is part of what software engineers do. If you find it hard - tough, but it's something you need to learn to deal with.
ima
+3  A: 

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
     } 
 }; 
Alexander Poluektov
Not sure I understand what you mean. C++ type resolution rules will resolve that to a call to Base<T>::exit. If you want the external function called exit, you should type ::exit().
Andreas Magnusson
No it doesn't. Dependent names and all that. Which is _exactly_ why you want to make it unambiguous.
MSalters
+5  A: 

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();).
herzmeister der welten
I want to say "this" in response to your entry. Using it (at least in the realm of C#) provides utterly complete clarity. At least in regards to C# I can't see a good reason not to use it.
chsh
Is this C#-specific? In Java, `this.Method()` does not make it clear that it's not a static method, it only makes it clear that you *thought* it wasn't a static method when you wrote the code :-)
Steve Jessop
If it's static, `this.Method()` doesn't compile in C# if that is what you meant.
herzmeister der welten
Gotcha. That one point is C#-specific then, because that does compile in Java.
Steve Jessop
O rly? I didn't know. What kind of sense makes that? I didn't know that Java is that weird.
herzmeister der welten
That weirdness is one of the many undesirable features Java inherited from C++.
finnw
Of course in C++, it's a desirable feature, because template code means that sometimes the programmer doesn't explicitly know the type of something, just has an object of that type (for instance it's a return value from a function overloaded on a template parameter, or some such -- the type depends on the template type, perhaps in a non-obvious way, and the template type is a variable from the POV of the programmer). In Java it appeared to be pointless, because in Java you can figure out the type of anything if you do the legwork. There may be worthwhile uses with generics, I don't know.
Steve Jessop
+1  A: 

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.

Vladimir
A: 

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.

dbemerlin
So, the first take on class Foo is flawless, you say?
Sorin Comanescu
This code is far from flawless, it's just there to demonstrate a point. I'd never use a public field (for a class) and i'd never name anything foo, foos or bar (and i rarely use count). The point is: You are seldom working on your own and other programmers might not read your code and overwrite your variables with local variables so it's always good to use _this_ to make sure no matter what your colleagues do, it won't have side effects on your code (ofc it might still happen but the chances are better that it wont).
dbemerlin
I really can't see how using (or not using) this can make a difference in first Foo's implementation. Altering state only to return it (!!!) from a method is so ... weird and confusing per se that the whole "this" issue becomes irrelevant. I can see your point (although I would rather go with naming conventions) but I believe the example you came with is too stretched.
Sorin Comanescu
I'm not a fan of prefixes or suffixes for Variables as they _look_ more irritating than "this." (but that's a matter of taste). _foo = _bar; _bar++; _bar = _foo - _baz; ... it just looks horrible. "this." might be longer to type but since programmers should always use descriptive names it fits better since the "_" is just another name for "this." and it's hardly descriptive. Maybe if the inventors of "this" had named it "t" more people would be using it :)
dbemerlin
Hmm. I see your point, but the colleague has added a local variable with a name *which is already used in the same function*. I'm not sure he should to be protected from this kind of stupidity - or at least if his mistake isn't absurdly stupid then your functions are too long. Next time he'll be shadowing your local variables: `int a; if (some_condition) ++a; return a;` -> `int a; if (new_condition) { int a = 5; use_a(a); if (some_condition) ++a; } return a;`. And he'll have got into the habit of thinking he doesn't have to read functions before modifying them, so he'll expect this to work ;-)
Steve Jessop
Mind you, I spent several years writing full-time in a kind of pseudo-assembly language, where "local variables" were registers i0, i1, i2... and didn't need to be declared. That teaches you to check whether a name is already in use before using it, I can tell you.
Steve Jessop
+2  A: 

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; }
mfx
would be avoidable by using void setX(int newX) { x = newX; } ;)
dbemerlin
underscores for member variables solve this problem, and ensure you never have a stackoverflow
Chris S
The eclipse "generate setter" editor wizard produces this kind of code, so one can assume that it is idiomatic java. I haven't seen underscored member variables since i stopped writing C++ (10 years ago).
mfx
+3  A: 

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)

Chris S
Don't use leading underscores to name variables in C++. If you want underscores, use trailing underscores, as in `myVar_` -- that's what I do, and it's conformant.
John Dibling
@John: using an _m prefix is also conformant, the problem is when someone else comes along and calls a member variable _Var.
Steve Jessop
@Steve: True enough, but why play that close to traffic? :)
John Dibling
Oh, I don't like the `_m` prefix, and for preference I use a 1-letter prefix `m` or `i` (for "instance", from Symbian) if I use anything at all. I just don't want a weak argument against it (that it's 1 bit away from being non-conformant) to get in the way of the far stronger but less technically-based "My eyes! The goggles do nothing!" argument ;-)
Steve Jessop
I haven't done enough C++ to make an informed comment, but for C# the pluses of underscores also include no stackoverflow errors for typos with get{}` with properties, and all your member variables being top of the list for intellisense.
Chris S
+3  A: 

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.

bretik
Didn't know about StyleCop. Looks good.
frou
Interesting. The point about static and instance members is good.
Benny Jobigan
A: 

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
  }
}
A: 

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.

Ether
A: 

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.

fastcodejava