C# Language Issues
These issues are specific to the C# language. These are the dark side of the specification that fell under the table, only to re-emerge as real pains for people who actually use the language on a day-to-day basis.
Namespaces resolved before classes
C# resolves visible namespaces before visible classes. This leads to some cases where unambiguous code results in an error, while logically ambiguous code compiles fine!
Lack of "isnot" operator
C# provides an is operator, but not an isnot
operator. This makes testing for an object not of a certain type clumsier
than it could be:
if ( !( o is MyType ) )
{
Blah();
}
versus
if ( o isnot MyType )
{
Blah();
}
Annoying scope protection rules
C# insists on protecting you from accidentally overriding the scope of a variable at a lower scope within your functions. If we're that irresponsible, why does it allow you to override the scope of a class-level variable at function level?
This is bad:
public void foo()
{
int x = 4;
// ...
UseValue( x );
for ( int i = 0; i < 100; i++ )
{
int x = -1; // <-- is it really so bad if I did this?
// ...
UseValue( x );
x++;
}
UseValue( x );
}
but this is okay?
public void foo()
{
int _x = 4; // Accidentally added underscore to variable name - where are you now C#?!?
// ...
UseValue( _x );
}
int _x = -1;
I don't like the compiler trying to second-guess what I'm writing. It's not even consistent where it gives you "help".
Interface casting
If you've defined a method using the explicit interface method notation, you can only refer to that method after casting the object to the interface. Why not pick up the correct method using the standard rules and throw an error in cases where there might be ambiguity?
Derived interface casting
If you derive from an interface that derives from another interface, you need to explicitly specify which interface your method is implementing a method for if you're using the explicit interface method notation.
interface IA
{
int X();
}
interface IB : IA
{
int Y();
}
public class C : IB
{
IB.X(); // <-- Can't do this - I have to know about IA!
IB.Y();
}
and then:
// ... C c = new C(); IB b = ( IB )c; b.X(); // <-- Can't do this - need to cast to IA! // ...
Switch statement scoping
C# inherited the switch statement from C++. Good. C# added
explicit gotos between labels. Good. C# forgot to remove the lame
scoping rules of switch statements. Bad! Since you're doing an explicit jump
between labels, why not have an implicit lexical scope for each set of labels?
switch ( i )
{
case 1:
int x = 4;
UseX( x );
break;
case 2:
int x = 5;
UseX( x ); // <-- This shouldn't be an error!
break;
}
typeof() doesn't apply to methods
You can't use typeof() on a method. The compiler should have the
smarts to pick out the method you're referencing and give you a
MethodInfo object.
class C{
public void foo( int x ) { ... }
}
MethodInfo mi = typeof( C.foo(int) );
Back to 101 Things I Hate About .NET