Jump to content

  • Log In with Google      Sign In   
  • Create Account

"this" keyword question


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
14 replies to this topic

#1 NUCLEAR RABBIT   Members   -  Reputation: 254

Like
0Likes
Like

Posted 13 April 2013 - 05:48 PM

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());
		}
	}
}


 


------------------------My band: RISE OVER ME!

Sponsor:

#2 Servant of the Lord   Crossbones+   -  Reputation: 21000

Like
5Likes
Like

Posted 13 April 2013 - 06:02 PM

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


Edited by Servant of the Lord, 13 April 2013 - 06:02 PM.

It's perfectly fine to abbreviate my username to 'Servant' rather than copy+pasting it all the time.
All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.
Of Stranger Flames - [indie turn-based rpg set in a para-historical French colony] | Indie RPG development journal

[Fly with me on Twitter] [Google+] [My broken website]

[Need web hosting? I personally like A Small Orange]


#3 Cornstalks   Crossbones+   -  Reputation: 6991

Like
5Likes
Like

Posted 13 April 2013 - 06:24 PM

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.

Edited by Cornstalks, 13 April 2013 - 06:32 PM.

[ 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 ]

#4 0r0d   Members   -  Reputation: 819

Like
0Likes
Like

Posted 13 April 2013 - 06:59 PM

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.  



#5 Servant of the Lord   Crossbones+   -  Reputation: 21000

Like
3Likes
Like

Posted 13 April 2013 - 07:53 PM

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.


It's perfectly fine to abbreviate my username to 'Servant' rather than copy+pasting it all the time.
All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.
Of Stranger Flames - [indie turn-based rpg set in a para-historical French colony] | Indie RPG development journal

[Fly with me on Twitter] [Google+] [My broken website]

[Need web hosting? I personally like A Small Orange]


#6 Chad Smith   Members   -  Reputation: 1143

Like
0Likes
Like

Posted 13 April 2013 - 11:25 PM

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.



#7 0r0d   Members   -  Reputation: 819

Like
3Likes
Like

Posted 13 April 2013 - 11:56 PM

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.



#8 Servant of the Lord   Crossbones+   -  Reputation: 21000

Like
2Likes
Like

Posted 14 April 2013 - 01:26 AM

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


It's perfectly fine to abbreviate my username to 'Servant' rather than copy+pasting it all the time.
All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.
Of Stranger Flames - [indie turn-based rpg set in a para-historical French colony] | Indie RPG development journal

[Fly with me on Twitter] [Google+] [My broken website]

[Need web hosting? I personally like A Small Orange]


#9 0r0d   Members   -  Reputation: 819

Like
2Likes
Like

Posted 14 April 2013 - 03:51 AM

...

...

 

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.



#10 tanzanite7   Members   -  Reputation: 1378

Like
2Likes
Like

Posted 14 April 2013 - 04:51 AM

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.

Edited by tanzanite7, 14 April 2013 - 05:12 AM.


#11 Servant of the Lord   Crossbones+   -  Reputation: 21000

Like
0Likes
Like

Posted 14 April 2013 - 04:15 PM

@0r0d: You're right - people with a clean slate should start using the best habit available, which isn't 'this->'.

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.

I never considered that. wacko.png I'll check if my IDE (QtCreator) has that feature and enable it (Edit: Can't find it. I guess I can get used to using the keyboard shortcut). I'll also check if it can visually distinguish from local and member variables (Edit: hmm, yes it can, and it was already enabled. I hadn't noticed it - I'll make it more apparent in the coloring).

If it can, and after getting used to it for a month or two, I might do a 'Replace All' of my 'this->' to ''. It might cause a few compile-time errors, but it'll cause no run-time errors in my codebase, so it'd be less than an hour's work to fully convert the code itself. The real conversion delay is how long it takes me to change. Probably only two weeks or so.
It's perfectly fine to abbreviate my username to 'Servant' rather than copy+pasting it all the time.
All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.
Of Stranger Flames - [indie turn-based rpg set in a para-historical French colony] | Indie RPG development journal

[Fly with me on Twitter] [Google+] [My broken website]

[Need web hosting? I personally like A Small Orange]


#12 0r0d   Members   -  Reputation: 819

Like
0Likes
Like

Posted 14 April 2013 - 05:58 PM

The real conversion delay is how long it takes me to change. Probably only two weeks or so.

 

That's usually the main reason why people dont change coding styles, although obviously it's mandated when you go to work someplace... normally.  As far as myself, I try to logically analyze what I do and change if there's a more effective/efficient way.  If the only reason to not change is that I'm used to it, then I just force myself.  It's a small hit up front, but it always pays off in the end.  This definitely means that when I look at very old code, I can see big differences, but if it's code I'm using again then I just go through as I see it and edit it to the new style.  With tools like Visual Assist, changing the names of variables is extremely easy and fast.


Edited by 0r0d, 14 April 2013 - 05:59 PM.


#13 Postie   Members   -  Reputation: 1117

Like
0Likes
Like

Posted 15 April 2013 - 07:21 AM

Two examples that spring to mind:

 

1) passing the current class as a parameter to a function (covered by Servant of the Lord), and ...

2) calling an overloaded constructor in the same class, ie something like:

 

class Test
{
    public Test(int param)
    {
            
    }
 
    public Test(int param1, int param2) : this(param1)
    {
            
    }
} 

 


Currently working on an open world survival RPG - For info check out my Development blog: ByteWrangler

#14 SeraphLance   Members   -  Reputation: 1454

Like
1Likes
Like

Posted 15 April 2013 - 07:47 AM

It's been covered fairly thoroughly by now in this context, but "this" is one of those keywords you may never have to use depending on your coding style.  In my personal stuff, I don't decorate my member variables, so I end up using the keyword a lot, as it's typically advised *not* to mangle your parameter names just so you avoid typing "this".  Parameters are part of your interface, and you want that as clean as possible.  Typically, if you don't decorate your fields (for instance with m_*, or *_), the best name for that field is the one you probably call it in the first place, so why hunt for another?

 

There is however, another, more important (since there's not really any other way to do this one) application of the "this" keyword that I'm surprised hasn't been mentioned:  self-returning.  Very important for fluent interfaces.  Some examples:

 

public class MyStringBuilder
{

  //constructor and stuff
  public MyStringBuilder Append(string newString)
  {
    //memory reallocation stuff -- probably push onto the end of a vector/list
    //depending on language.
    return this;
    
  }

  public string ToString()
  {
    //do stuff to turn our array into a string.
  }

}

public class WidgetContainer
{
  //fields and constructor and stuff
  public WidgetContainer addCheckBox( /*parameters*/ )
  {
    widgets.add(new CheckBox( /*args*/ );
    return this;
  }

  public WidgetContainer addRadioButton( /*parameters*/ )
  {
    widgets.add(new RadioButton( /*args*/ );
    return this;
  }

  //et al.
}

//meanwhile... somewhere in main.

var sb = new MyStringBuilder();
sb.append("Hello").append(", ").append("World").append("!"); //a contrived example.

var wc = new WidgetContainer();
wc.addCheckBox(200,300).addCheckBox(200, 310).addCheckBox(200, 320).addButton(200, 330, "Start!", someCallbackFunctor);

 

EDIT:  I had never seen those Extension Methods before... That's really cool.


Edited by SeraphLance, 15 April 2013 - 08:01 AM.


#15 dilyan_rusev   Members   -  Reputation: 1068

Like
0Likes
Like

Posted 15 April 2013 - 10:40 AM

In my previous work place we were required to use "this" (it was part of the naming convention). At my current job, it is the opposite - it is a bit closer to the Java convention (used only in constructors IF there is a naming conflict... which isn't a poor programming practice for constructors).

I've been doing it both ways for years, and I tend to disagree with 0r0d. It does not decorate *only* fields, but methods as well. Before I started using this (which is slow because of the '.', but a lot faster than c++'s '->' which involves Shift as well), I thought it was slow, inefficient and that it littered the code. And then I changed my mind :) The reasons for this are:

  • In a huge code base, it is really important what comes from where
  • Coloring is cool, but is slow as hell, often buggy, even on powerful, high-end machines
  • Most of the time, I read code. When you deal with a huge code base, with tons of stuff you haven't written, you want to be able to easily analyze the API.
    • First, this immediately tells you the scope of variables and methods.
    • Second, this tells you immediately what is static, and what is instance-bound.
    • For that matter, part of the naming convention was to prefix static methods with their class names even inside the class itself. To your eyes it might seem as an abomination, but it is quite helpful when you swim in unfamiliar code.

Overall, the benefits are that you get a lot of information about the code with just a glance.

The downside (especially with prefixing static methods) is that you often get well beyond the 80 characters per line limit. And nothing kills readability more than horizontal scrolling. This is why we had unofficial coding conventions about how to split the code on multiple lines, so that it remains readable.

 

@SeraphLance - For the sake of readability and API extendability, don't use method extensions or method chaining. For that matter, fluent API != method chaining. Here are some reasons why I've come to dislike both after years of using them (and designing APIs with them)

  • When you see timeInSeconds.Normalize(), you've got no clue what is going on. Is this a method? Is this an extension method? Which class provides this extension? Nothing stops Joe to add the next extension method in another class. The IDE can help you, but you don't have this information at first glance, so it slows down readability
  • Extension methods depend on the namespace. So you have two problems:
    • Namespace pollution - when you put too many extension methods in some global namespace (God forbid you put anything in System!)
    • Discoverability - it is very difficult for end users to use your API. What happens usually is that they find out some of your methods "don't work" when they haven't included the right namespace, or they don't ever discover them.
  • Extension methods are static,
    • ... and they inherit all the Builder pattern problems with extensibility. Normal methods can be made virtual and extended by the end user. Static methods are defined in a completely independent class (hopefully one), so they can't be overridden. What's more, they can only access the public members of the class they extend, so extension methods might have bad performance or may not even be able to implement the required functionality without an interface change.
    • You might want to add a method with the same name in the next version of your API... what happens then? Obviously you can't for readability's sake, but then you have to come up with some unintuitive name.
  • Method chaining is bad for debugging. What most users of the API tend to is is stack method calls on a single line. When you don't chain methods, stepping into the correct method is a piece of cake, because, of course, you will invoke no more than one method per line, right?
  • Method chaining is bad for readability. I cringe when I see how most people write their Linq queries... it is a very bad idea to have no coding style about vertical space, yet most work places don't have one. So you have lots of different coding styles when invoking the method chain.
  • Fluent APIs are extremely difficult to come up with. For every non-trivial fluent API, you've got different faces for the concepts you're abstracting. If you put in inheritance, you usually end up all your faces as generic classes with a lot of generic parameters, like Base<TImplementation, TWhatIActaullyNeed> (this happens because you want auto-completion to work when the user chains the super class methods of a derived class). It is way more complicated than composition and/or decorator pattern (which is difficult in terms of discoverability in itself.
 




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS