70

I have been trying to follow StyleCop's guidelines on a project, to see if the resulting code was better in the end. Most rules are reasonable or a matter of opinion on coding standard, but there is one rule which puzzles me, because I haven't seen anyone else recommend it, and because I don't see a clear benefit to it:

SA1101: The call to {method or property name} must begin with the 'this.' prefix to indicate that the item is a member of the class.

On the downside, the code is clearly more verbose that way, so what are the benefits of following that rule? Does anyone here follow that rule?

Drew Noakes
  • 300,895
  • 165
  • 679
  • 742
Mathias
  • 15,191
  • 9
  • 60
  • 92
  • 11
    Keep in mind that StyleCop is intended to be configured for your needs, and the default settings may not be optimal. Not all StyleCop rules are equally sane either, and, in fact, I recall there being some that were downright contradictory, and impossible to satisfy when both are enabled. If you already have a coding style that works for you in that aspect (e.g. prefix fields with `_` seems to be popular), stick to it, and change StyleCop settings accordingly. – Pavel Minaev Oct 13 '09 at 19:53
  • Lots of discussion on this here as well: http://stackoverflow.com/questions/1499446/best-practice-for-c-auto-implemented-property-and-local-variable-that-differ-onl – womp Oct 13 '09 at 20:00
  • As others have noted, StyleCop attempts to enforce many arbitrary and seeminglyr absurd rules. Not all are meant to be followed and you should strive to configure StyleCop according to the standards you see most practical. – Nathan Taylor Oct 13 '09 at 20:02
  • 9
    The default settings represent a standard though, so if your goal is to have code that conforms to the standard created by a body outside of your team, then don't customize the rules. – JeremyWeir Oct 13 '09 at 20:04
  • 8
    @Pavel: I assume StyleCop ships with the default rules Microsoft follows, and I would believe that these rules have a rationale. Before changing the default, I'd like to understand why it was set that way! – Mathias Oct 13 '09 at 20:14
  • 3
    @Mathias - some of the rules, like where to put your `using` declarations, aren't even satisfied by the class templates. I'm not sure all are sane. – Marc Gravell Oct 13 '09 at 21:25
  • 1
    @Mathias: If I recall the history of StyleCop, it was not originally used Microsoft-wide. I would not assume the StyleCop rules are the ones used across Microsoft. Especially not the "this." rule. – John Saunders Feb 24 '10 at 01:44
  • @Marc yes this is extremely annoying: having to re-do the default templates to pass StyleCop is absurd. One would hope that Visual Studio's default templates would satisfy the alleged internal coding standard! – Mathias Feb 25 '10 at 18:43

9 Answers9

98

I don't really follow this guidance unless I'm in the scenarios you need it:

  • there is an actual ambiguity - mainly this impacts either constructors (this.name = name;) or things like Equals (return this.id == other.id;)
  • you want to pass a reference to the current instance
  • you want to call an extension method on the current instance

Other than that I consider this clutter. So I turn the rule off.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
71

It can make code clearer at a glance. When you use this, it's easier to:

  • Tell static and instance members apart. (And distinguish instance methods from delegates.)
  • Distinguish instance members from local variables and parameters (without using a naming convention).
Jeff Sternal
  • 47,787
  • 8
  • 93
  • 120
  • 6
    Agreed about the class fields vs. local variables. The _ or m_ notation for class fields looks like an archaism to me, and this rule is a reasonable way to replace it while keeping things readable. – Mathias Oct 13 '09 at 20:03
  • 1
    While this answers the question "Why is this a good style rule", the link provided by jayrdub provides a better answer to the question "Why does StyleCop enforce this rule". – Stephen C. Steel Oct 13 '09 at 20:53
  • 8
    You can accomplish exactly the same thing by using unique affixes on member variables (e.g., `m_name` versus `name`) and none on local and parameter variables. It's a question of taste, though. – David R Tribble Oct 13 '09 at 21:02
  • 2
    @Loadmaster - I would add too that with the use of an affix/prefix such as underscore, it enforces usage through the name whereas with the 'this' keyword you have to rely on tools like StyleCop to enforce the usage. – jpierson Mar 01 '11 at 03:36
  • 7
    If you're using `this` to distinguish members then you're basically using a naming convection, so it's no better than prefixing with `_` or `m_`. In fact it's worse as using `this` requires more characters. – Sean Jul 13 '15 at 14:16
  • 4
    Visual studio suggests removing the "this" that stylecop suggested I add. Can't they make up their minds? – Cogwheel Oct 01 '15 at 18:06
  • 1
    Or use syntax-highlighting that differentiates these things, then you get the benefits without the clutter – BlueRaja - Danny Pflughoeft Jun 13 '17 at 22:32
  • Microsoft's [Coding Conventions](https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/coding-conventions) say to use the `_` prefix for the private and internal fields. It seems IntelliSense is also looking out for the underscore, specifically. – benJephunneh Feb 02 '22 at 20:20
41

I think this article explains it a little

A Brief History Of C# Style

...a brilliant young developer at Microsoft (ok, it was me) decided to take it upon himself to write a little tool which could detect variances from the C# style used within his team. StyleCop was born. Over the next few years, we gathered up all of the C# style guidelines we could find from the various teams within Microsoft, and picked out all of best practices which were common to these styles. These formed the first set of StyleCop rules. One of the earliest rules that came out of this effort was the use of the this prefix to call out class members, and the removal of any underscore prefixes from field names. C# style had officially grown apart from its old C++ tribe.

Borislav Ivanov
  • 4,684
  • 3
  • 31
  • 55
JeremyWeir
  • 24,118
  • 10
  • 92
  • 107
  • 1
    Thanks, nice to have the inside story! – Mathias Oct 13 '09 at 20:09
  • 22
    Thanks for the link. It tells me why the StyleCop rules are largely crap - they're a bunch of rules from scattered teams, and not a single, well thought-out set of rules, researched to determine that they are, in fact, best, for teams of all levels of ability. – John Saunders Feb 24 '10 at 01:48
  • Well in 2019 anyway, stylecop.analyzers seems to have some pretty strong rules and I leave most enabled; only a few like this and banning #region are really questionable. Would like better customization and coverage of a few other things e.g. line length as part of the ruleset, but for the most part, it's great. I mean, I'm only here because I look up the merit of every rule. – person27 Sep 02 '19 at 21:39
  • Nov 4th 2020, link is broken. – spikey_richie Nov 04 '20 at 10:34
23
this.This 
this.Does 
this.Not 
this.Add 
this.Clarity 
this.Nor 
this.Does 
this.This 
this.Add 
this.Maintainability 
this.To 
this.Code

The usage of "this.", when used excessively or a forced style requirement, is nothing more then a contrivance used under the guise that there is < 1% of developers that really do not understand code or what they are doing, and makes it painful for 99% who want to write easily readable and maintainable code.

As soon as you start typing, Intellisence will list the content available in the scope of where you are typing, "this." is not necessary to expose class members, and unless you are completely clueless to what you are coding for you should be able to easily find the item you need.

Even if you are completely clueless, use "this." to hint what is available, but don't leave it in code. There are also a slew of add-ons like Resharper that help to bring clarity to the scope and expose the contents of objects more efficiently. It is better to learn how to use the tools provided to you then to develop a bad habit that is hated by a large number of your co-workers.

Any developer that does not inherently understand the scope of static, local, class or global content should not rely on "hints" to indicate the scope. "this." is worse then Hungarian notation as at least Hungarian notation provided an idea about the type the variable is referencing and serves some benefit. I would rather see "_" or "m" used to denote class field members then to see "this." everywhere.

I have never had an issue, nor seen an issue with a fellow developer that repeatedly fights with code scope or writes code that is always buggy because of not using "this." explicitly. It is an unwarranted fear that "this." prevents future code bugs and is often the argument used where ignorance is valued.

Coders grow with experience, "this." is like asking someone to put training wheels on their bike as an adult because it is what they first had to use to learn how to ride a bike. And adult might fall off a bike 1 in 1,000 times they get on it, but that is no reason to force them to use training wheels.

"this." should be banned from the language definition for C#, unfortunately there is only one reason for using it, and that is to resolve ambiguity, which could also be easily resolved through better code practices.

ChrisCW
  • 520
  • 5
  • 5
  • 1
    well put. I couldn't think of any bug we had the last few years due to the missing 'this'. Nice comparison with the training wheels :) – Stefan Sieber May 31 '16 at 11:16
  • Well put. Unnecessary clutter as far as I'm concerned. – Craig Nov 08 '17 at 23:21
  • 2
    8 years later, "this." is much more popular thanks to TypeScript. Underscore looks terrible, and you can' differentiate between instance classes, methods, or properties. – Chris Fremgen May 10 '22 at 11:59
  • 2
    `Any developer that does not inherently understand the scope of static, local, class or global content should not rely on "hints" to indicate the scope.` – Isn't `_` or `m` also a hint? – glen-84 Jul 24 '22 at 09:17
11

A few basic reasons for using this (and I coincidentally always prefix class values with the name of the class of which they are a part as well - even within the class itself).

1) Clarity. You know right this instant which variables you declared in the class definition and which you declared as locals, parameters and whatnot. In two years, you won't know that and you'll go on a wondrous voyage of re-discovery that is absolutely pointless and not required if you specifically state the parent up front. Somebody else working on your code has no idea from the get-go and thus benefits instantly.

2) Intellisense. If you type 'this.' you get all instance-specific members and properties in the help. It makes finding things a lot easier, especially if you're maintaining somebody else's code or code you haven't looked at in a couple of years. It also helps you avoid errors caused by misconceptions of what variables and methods are declared where and how. It can help you discover errors that otherwise wouldn't show up until the compiler choked on your code.

3) Granted you can achieve the same effect by using prefixes and other techniques, but this begs the question of why you would invent a mechanism to handle a problem when there is a mechanism to do so built into the language that is actually supported by the IDE? If you touch-type, even in part, it will ultimately reduce your error rate, too, by not forcing you to take your fingers out of the home position to get to the underscore key.

I see lots of young programmers who make a big deal out of the time they will save by not typing a character or two. Most of your time will be spent debugging, not coding. Don't worry so much about your typing speed. Worry more about how quickly you can understand what is going on in the code. If you save a total of five minutes coding and win up spending an extra ten minutes debugging, you've slowed yourself down, no matter how fast you look like you're going.

YrthWyndandFyre
  • 149
  • 1
  • 3
  • 2
    Your last paragraph essentially contradicts your 3rd point. And anybody who's a touch typist and has the move out of the home position to get to the underscore key is... not a touch typist. – sliderhouserules Jan 30 '15 at 21:01
  • Oops, typo. "has *to* move out of... " It won't let me edit my comment after 5 minutes. – sliderhouserules Jan 30 '15 at 21:24
10

Note that the compiler doesn't care whether you prefix references with this or not (unless there's a name collision with a local variable and a field or you want to call an extension method on the current instance.)

It's up to your style. Personally I remove this. from code as I think it decreases the signal to noise ratio.

Just because Microsoft uses this style internally doesn't mean you have to. StyleCop seems to be a MS-internal tool gone public. I'm all for adhering to the Microsoft conventions around public things, such as:

  • type names are in PascalCase
  • parameter names are in camelCase
  • interfaces should be prefixed with the letter I
  • use singular names for enums, except for when they're [Flags]

...but what happens in the private realms of your code is, well, private. Do whatever your team agrees upon.

Consistency is also important. It reduces cognitive load when reading code, especially if the code style is as you expect it. But even when dealing with a foreign coding style, if it's consistent then it won't take long to become used to it. Use tools like ReSharper and StyleCop to ensure consistency where you think it's important.

Using .NET Reflector suggests that Microsoft isn't that great at adhering to the StyleCop coding standards in the BCL anyway.

Drew Noakes
  • 300,895
  • 165
  • 679
  • 742
  • 2
    .NET Reflector does not show you the source code as written, e.g. it's output tells you very little about the sytle of the code, it is a decompiler after all. – Ian Ringrose Jan 11 '10 at 09:51
  • 3
    @Ian - you're right that `this` gets compiled away, but other things such as fields with underscore prefixes remain. If you check the source code that MS now allows you to download (and tools like ReSharper navigate to) you'll see varying coding styles across the BCL too. – Drew Noakes Jan 11 '10 at 13:48
4

I do follow it, because I think it's really convenient to be able to tell apart access to static and instance members at first glance.

And of course I have to use it in my constructors, because I normally give the constructor parameters the same names as the field their values get assigned to. So I need "this" to access the fields.

Jeff Sternal
  • 47,787
  • 8
  • 93
  • 120
Maximilian Mayerl
  • 11,253
  • 2
  • 33
  • 40
3

In addition it is possible to duplicate variable names in a function so using 'this' can make it clearer.

class foo {
  private string aString;

  public void SetString(string aString){
    //this.aString refers to the class field
    //aString refers to the method parameter        
    this.aString = aString; 
  }
}
Michael Gattuso
  • 13,020
  • 2
  • 25
  • 29
  • I see this practice often within constructors where many times the parameters match the names of various private fields and or properties to which adding the 'this.' prefix helps to clarify the code and in some cases avoid name collisions. – jpierson Mar 01 '11 at 03:45
1

I follow it mainly for intellisense reasons. It is so nice typing this. and getting a consise list of properties, methods, etc.

James Lawruk
  • 30,112
  • 19
  • 130
  • 137
  • 7
    Fine, but once you're done getting the list, `this.` is no longer of any value. Consider: if there were a keystroke you could type that would produce the same IntelliSense list as typing "`this.`", then there would be very little need to type "'`this.'". – John Saunders Feb 24 '10 at 01:46
  • I have heard this particular excuse before, hitting this. for intellisense to me just smacks of lazyness as the this. is not required as the previous comment points out. Plus there are other ways to invoke intellisense. – krystan honour Apr 14 '10 at 10:06
  • For the same reason I used to type '.' in Java code because, if I remember correctly, tools like JBuilder would pick it up and offer intelli-sense. So I think in Jave the kewword 'this' can be committed altogether. – jpierson Mar 01 '11 at 03:48