I'm glad C# doesn't let you access static members 'as though' they were instance members. This avoids a common bug in Java:
Thread t = new Thread(..);
t.sleep(..); //Probably doesn't do what the programmer intended.
On the other hand, it does let you access static members 'through' derived types. Other than operators (where it saves you from writing casts), I can't think of any cases where this is actually helpful. In fact, it actively encourages mistakes such as:
// Nasty surprises ahead - won't throw; does something unintended:
// Creates a HttpWebRequest instead.
var ftpRequest = FtpWebRequest.Create(@"http://www.stackoverflow.com");
// Something seriously wrong here.
var areRefEqual = Dictionary<string, int>.ReferenceEquals(dict1, dict2);
I personally keep committing similar errors over and over when I am searching my way through unfamiliar APIs (I remember starting off with expression trees; I hit BinaryExpression.
in the editor and was wondering why on earth IntelliSense was offering me MakeUnary
as an option).
In my (shortsighted) opinion, this feature:
- Doesn't reduce verbosity; the programmer has to specify a type-name one way or another (excluding operators and cases when one is accessing inherited static members of the current type).
- Encourages bugs/ misleading code such as the one above.
- May suggest to the programmer that static methods in C# exhibit some sort of 'polymorphism', when they don't.
- (Minor) Introduces 'silent', possibly unintended rebinding possibilities on recompilation.
(IMO, operators are a special case that warrant their own discussion.)
Given that C# is normally a "pit of success" language, why does this feature exist? I can't see its benefits (other than 'discoverability', which could always be solved in the IDE), but I see lots of problems.