"this" keyword question

Started by
13 comments, last by dilyan_rusev 11 years ago

So I have a question about the keyword this. I made a simple test program to test it, and it seems like it doesn't matter whether I use the this keyword in the display(). I tried running with and without it and get the same result, so my question is what is the advantage of using the this keyword?

Game.cs


namespace ClassPract
{
	public class Game
	{
		public static void Main() 
		{
			Player player = new Player("Jack", 23);

			player.display();
		}
	}
}

Player.cs


using System;

namespace ClassPract
{
	public class Player
	{
		String name;
		Byte age;

		public Player (String t_name, Byte t_age)
		{
			name = t_name;
			age = t_age;
		}

		public String getName() {
			return name;
		}

		public Byte getAge() {
			return age;
		}

		public void display() {
			Console.WriteLine("name:\tage:\n{0}\t{1}", this.getName(), this.getAge());
		}
	}
}


Advertisement

I'm not sure about C#, but in C++ you normally don't have to use the 'this' keyword either - but it certain circumstances it is important.

One example would be passing the class' pointer to a function that takes a pointer of type 'Player' as an argument. What else besides 'this' could you give it, from within the class?


public void MemberFunc()
{
            nonMemberfunction_ThatTakesAClassPointer(this); //How else would you pass it, without jumping through hoops?
}

Another example would be declaring a local variable that has the same name as a member-variable.

In C++, the local variable would get precedence, unless you explicitly used 'this->variableName'.

I tried running with and without it and get the same result, so my question is what is the advantage of using the this keyword?

In this situation, there's no advantage/disadvantage. I'll expand on what Servant of the Lord said and add a few things. Let's say you have a constructor that takes a parameter named "x" and sets a private variable named "x" like this:
public class MyClass
{
    private int x;
 
    public MyClass(int x)
    {
        x = x;
    }
}

What does this do? Does it set MyClass's x to the parameter x? Nope! It sets the parameter x to itself, which is... useless. Let's try this:
public class MyClass
{
    private int x;
 
    public MyClass(int x)
    {
        this.x = x;
    }
}
There, now this works! "this" is used to say "I want the class's variable x, not the parameter x" (it's important to use it here because it's ambiguous which x you're using). In other situations where the variable names aren't the same (i.e. there isn't an ambiguity as to which variable you mean), "this" isn't needed.

However, even in situations where "this" isn't technically needed (like in the situation you posted), some people will still use it to make it explicitly clear that they're using something from the class and not a local variable/function. This is more of a coding style (and it serves the same purpose as some people prefixing member variables with "m"/"m_"), but it's by no means "the standard" coding style.

I also want to point out that "this" is used when making Extension Methods. You're not doing that here, but it's worth pointing out.
[size=2][ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]

So I have a question about the keyword this. I made a simple test program to test it, and it seems like it doesn't matter whether I use the this keyword in the display(). I tried running with and without it and get the same result, so my question is what is the advantage of using the this keyword?

In your example there's no advantage. The disadvantage is that you're writing redundant code, and most programmers will look at that and think that you dont know what you're doing.... and wonder what other bizarre programming habits you have.

If you do find yourself in the situation where you need it because your member variable is named the same as a local one, you might want to rethink your naming conventions, or lack thereof. Prefixing class member names with "m" or "m_" is in most cases a good idea, not just because it helps to avoid naming problems, but also because it gives important information to anyone reading the code.

In your example there's no advantage. The disadvantage is that you're writing redundant code, and most programmers will look at that and think that you dont know what you're doing.... and wonder what other bizarre programming habits you have.

I always use 'this' for member-variables, as part of my personal programming style - but I'm consistent in doing so.

My rationale:
A) It differentiates between member-variables and local-variables.


this->memberVariable = 200;
localVariable = 200;

Other people prefer prefixing their member-variables with something like 'my' (i.e. myMemberVariable) - it's the same idea, but with a little more typing on my part.

B) It kicks in the intellisense. Typing 'memberVariable', intellisense won't kick in immediately until I start typing. I have to remember what the first letter of the variable's name is, which normally isn't a problem. If I type 'this->' the intellisense kicks in and gives me a list of all the member variable names.

Yeah, kinda silly rolleyes.gif, but I've never minded the extra typing. this-> this-> this-> this-> this-> I just pretend 'this->' is the namespace of member-variables. I fully type out std:: also. this-> is only a tenth of a second slower to type than std::.
I have to think while programming anyway, so it's not like I'm transcripting something where every word-per-minute counts.

In your example there's no advantage. The disadvantage is that you're writing redundant code, and most programmers will look at that and think that you dont know what you're doing.... and wonder what other bizarre programming habits you have.

I always use 'this' for member-variables, as part of my personal programming style - but I'm consistent in doing so.

My rationale:
A) It differentiates between member-variables and local-variables.


this->memberVariable = 200;
localVariable = 200;

Other people prefer prefixing their member-variables with something like 'my' (i.e. myMemberVariable) - it's the same idea, but with a little more typing on my part.

B) It kicks in the intellisense. Typing 'memberVariable', intellisense won't kick in immediately until I start typing. I have to remember what the first letter of the variable's name is, which normally isn't a problem. If I type 'this->' the intellisense kicks in and gives me a list of all the member variable names.

Yeah, kinda silly rolleyes.gif, but I've never minded the extra typing. this-> this-> this-> this-> this-> I just pretend 'this->' is the namespace of member-variables. I fully type out std:: also. this-> is only a tenth of a second slower to type than std::.
I have to think while programming anyway, so it's not like I'm transcripting something where every word-per-minute counts.

This is what I have believed also. When I program I most of time still need to think and the extra tenth or two that I spend typing some things out shouldn't bother me. I mean how many of us actually measure how many words we type in a minute while programming? That seems like one of the last things you should be doing.

Though I guess it's all in style. I myself am like you and use this-> just about all the time on member variables. I also type out std:: every where. Matter of fact don't think I typed using namespace std or even using std::string or anything like that since I first started learning. I almost feel if you're so worried about the extra bit of typing then a job like programming where you do a lot of typing isn't for you.

In your example there's no advantage. The disadvantage is that you're writing redundant code, and most programmers will look at that and think that you dont know what you're doing.... and wonder what other bizarre programming habits you have.

I always use 'this' for member-variables, as part of my personal programming style - but I'm consistent in doing so.

My rationale:
A) It differentiates between member-variables and local-variables.


this->memberVariable = 200;
localVariable = 200;

Other people prefer prefixing their member-variables with something like 'my' (i.e. myMemberVariable) - it's the same idea, but with a little more typing on my part.

B) It kicks in the intellisense. Typing 'memberVariable', intellisense won't kick in immediately until I start typing. I have to remember what the first letter of the variable's name is, which normally isn't a problem. If I type 'this->' the intellisense kicks in and gives me a list of all the member variable names.

Yeah, kinda silly rolleyes.gif, but I've never minded the extra typing. this-> this-> this-> this-> this-> I just pretend 'this->' is the namespace of member-variables. I fully type out std:: also. this-> is only a tenth of a second slower to type than std::.
I have to think while programming anyway, so it's not like I'm transcripting something where every word-per-minute counts.

If you want to get intellisense to work then prefixing your member variables with "m" is much better than "this->". All you're doing is making more work for yourself and littering your code with useless "this->". You're not making it any safer from error... you can still forget to write this-> and now you're using the wrong variable, because you have no naming difference between local and members. By prefixing the members you reduce this possible error because now you have much fewer places where you could screw up... you only have one declaration of the member variable in the class, versus multiple usage of it everywhere else.

It doesnt matter to me, though, feel free to spend your time typing all the redundant code you want. But, nothing you said is a valid reason to do it, and in fact the example of intellisense is actually a reason to NOT do it.

If you want to get intellisense to work then prefixing your member variables with "m" is much better than "this->".

Well, on my IDE, intellisense waits a full second or two to kick in when typing, but kicks in instantly when dereferencing a pointer, so I get to the intellisense faster. *shrugs*

I admit it is rather silly, but I figured I'd throw out one reason why someone such as myself might use it. It's 'silly', but not 'harmful'.

All you're doing is making more work for yourself and littering your code with useless "this->".

I'm not sure why you think it is 'littering' and 'useless'. It serves the same use as the 'my' prefix. Is the 'my' prefix littering also? Is std:: also littering and useless? I mean, after all, we could just have all C++ functions and classes be called std_string, or win32_CreateWindow. But that's littering too. But it's littering that serves a purpose: distinguishing names in one group from another.

You're not making it any safer from error... you can still forget to write this->

Granted. But it's a habit I chose to adopt, and I almost never forget it, just because it's second nature now. When I want a class variable, I type 'this->'. When I want a standard library class, I type 'std::'. And I very rarely forget to type 'std::'.

and now you're using the wrong variable, because you have no naming difference between local and members.

That's assuming my code even has with places where I overshadow one variable name with an identically named variable in a nested scope. Which I believe is poor practice and so I don't do that. The only place I ever have two variables accessible in the same scope to share the same name is the parameters of class constructors with initializer lists, because they mentally are the same variable, even if they technically aren't.


MyClass::MyClass(int memberVariable) : memberVariable(memberVariable)

By prefixing the members you reduce this possible error because now you have much fewer places where you could screw up... you only have one declaration of the member variable in the class, versus multiple usage of it everywhere else.

Aside from uses outside of the class entirely (and why should the class care about the implementation of the rest of the program, or vise-versa?), no variable within the class (local, global, or otherwise) shares the same variable name as a class' member-variable. That would be inviting errors. I don't need to explicitly protect from errors I'm not exposed to.

All you're doing is making more work for yourself
...
It doesnt matter to me, though, feel free to spend your time typing all the redundant code you want.

In my project currently are (project-wide search:


std::		(x3500)
this->		(x5332)
if(...)		(x2169)
for(...)	(x373)
//		(x33384) <- Lots of unnecessary typing.
/*		(x339)

When I'm thinking about code, whether my fingers are typing or not doesn't particularly matter. My typing speed really isn't the bottleneck, so I don't need to optimize for it.

What personally is the bottleneck for me is how fast I can think of what to type, how fast I can isolate bugs, how fast my code compiles (currently too slow - creates undesired interrupts in my workflow).
If I spend extra time typing 'this->' it's a reflex action done without thought. It's not using any resource that would be otherwise occupied. So I'm actually not wasting actual 'time', because it's almost always auto-piloted while I'm using the time to think.

Another point of optimization is how fast I can understand what's going on, when looking at code I've previously written months ago. This is my 'scan speed' - glancing over a piece of code, without tripping up on mental jars from unusual code usage, how fast can I read, process, and discard the information?

this-> actually helps in that category, since (once used consistently, and once familiar with the style) it's easier to parse it mentally as its own token.


variable = 357;
meow = myMeow;
marshmellowsAndCreme = "my text!"
myMongooseArmy = meow * myMarmoset;

vs:


variable = 357;
meow = this->Meow;
marshmellowsAndCreme = "my text!"
this->MongooseArmy = meow * this->Marmoset;

It's such a minor issue that I really don't think one is better than the other - nor do I advocate my way. I do strongly believe and advocate that consistency with whatever styles one uses is very important, and often more important than the choice of style itself.

I've actually considered switching to the 'my' prefix style, but found it such a non-issue that I've pushed it off to a far distant date several projects from now when I have a clean codebase (important changes to style I implement immediately, refactoring existing places in my code - unimportant style-changes can wait for a new empty project). I just don't find the pros and cons to be such as to require a change of style.
I'll try it sometime, and see if I like it better, but I don't feel any rush or see any need.

But perhaps I'm optimizing the wrong areas. Maybe I need to optimize my life-span by not spending over an hour writing a post debating something even less relevant than brace-styles. rolleyes.gif Well, too late now! laugh.png

...

...

Yup, a lot of things are subjective when it comes to coding style, conventions, formatting, and stuff like that. But anyway, my point is that if one way is better (even a little) than another, then that's what people starting out should be doing. For people like you who have already gotten accustomed to one way, changing is not as essential, unless it happens that the style you're used to is not widely used... in which case it might cause problems later on when you try to read other people's code or fit into a new job.

In this case, however, there is an actual measurable difference between prefixing members with "m" and "this->". One is 6x slower than the other, and introduces 6x as much duplicated text to the code. Now, to you this might be imperceptible, but to others it might not be. To me, for example, I can definitely notice the difference between getting intellisense to give me results after typing one letter, as opposed to having to type 6. Also, there are cases where having a smaller footprint for variable names is really helpful. Using "m" instead of "this->" helps to keep that small without losing any valuable information.

For me it is not really a question of typing more - it is readability. Adding more junk to the code that does ultimately nothing can not be a good thing IMO.

Also, i am strongly against code conventions that are solely risen out of tool/user limitations: tools change, but the code is what one has to live with. Delay in invoking intellisense is a good example of that (Systems Hungarian notion being the canonical example of shit hitting the fan rather fast). IDE is there to help you - not to own you and your code.

PS. Why not set the intellisense delay to 0 (as i have done)? It needs a bit of getting used to, but well worth it.

edit: One more thing, my current IDE (VS2012) has quite good coloring options. I know that a variable has an implicit "this" from the variable color alone. No need to notice whether it has "this->" written in front of it nor whether it starts with "m_" ... i do not have to read anything and i already know!

PS2. Of course, consistency is paramount and i am not saying you should start converting all your code - which is bound to be a massive undertaking and hard to justify. I am just saying that, IMMHO, what you do is bad practice and should be avoided if possible.

This topic is closed to new replies.

Advertisement