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.