Fine, since you promised. These are just the things that bug me most.
My least favorite thing so far is pointers, though. Having to declare variables as "fixed" indicates a fundamental problem: they're trying to add a low-level paradigm to a high-level language, and end up with ugly constructs like that. It doesn't have a good feeling to me.
I also hate operator overloading. To me, a + should always add and a << should always left-shift. C# provides operator overloading, which is something I can get over. However, when using, for example, delegates, you add all your events to your delegate with + and remove them with -. That kind of thing just isn't right, to me. Then when you want to find out if it's empty, you compare it to null. That's just confusing, it took me awhile to figure out how a non-reference variable could be null. In my opinion, it's exactly why operator overloading is bad.
Another thing I don't like is that they .. damnit, I got an email and left for 10 minutes, so I totally forget what I was writing. Ohwell.
Muwahahahaha, I didn't promise!
For the record, C# pointers don't always work with the fixed keyword. They only are used when you need to obtain a pointer to a heap-allocated, garbage-collected object. Arrays are heap-allocated except when using the stackalloc keyword:
unsafe void PointMe()
{
byte* ptr = stackalloc byte[80];
}
Stack-allocated memory is intrinsically cleaned up at the end of a function scope. The fixed keyword exists to inform the garbage collector not to automatically relocate an object during a garbage collection pass. As I've gone farther in my C# use, I do what I can to avoid using fixed in favor of other constructs (Marshal.AllocHGlobal, Marshal.AllocCoTaskMem, and stackalloc - as far as I'm concerned, Marshal.AllocHGlobal and AllocCoTaskMem are the same as using malloc).
For operator overloading, best practices indicate that the overloaded operators should be used only for the mathematical functions they represent. For instance, MBNCSUtil's BigInteger has overloaded operators for all of its numeric functions. Best practices further dicate that there should be named functions (such as Add()) for any overloaded operators.
As for delegates and events, I suppose it's a matter of preference:
this.btnOK.Click += new EventHandler(this.btnOK_Click);
// vs.
this.btnOK.addActionListener(new ButtonActionListener(this));
To me, += and .addXXX() pretty much equate to the same thing. I think of += as syntactic sugar - I can say
Delegate.Join(btnOK.Click, new EventHandler(btnOK_Click));
And you're mistaken about delegates and events - they *are* reference types. That's why you need to check for nullility.
I agree with you - I don't like e-mail. Particularly work things are notorious for pulling me away from important things like posting on the forums. I think we should make e-mail illegal immediately!