I answered a question in a C# forum the other day from someone looking to do runtime subclassing, similar to NMock. The question went something like this:
"How do I overload the equals/not-equals operators for my dynamically-created class?"
Well, being hot shit at code generation, I immediately responded with something like this:
"It's easy - just define two static methods called 'op_Equality' and 'op_InEquality'".
Then I actually tried it. Although it's quite possible to define and emit these methods correctly, it doesn't do you much good. Operator overloads are resolved at compile-time, not at run-time, so for a statement like this:
bool areEqual = (foo1 == foo2);
if you have overloaded '==' and '!=' on type Foo in the usual manner (ie statically), the compiler will find the overload and emit MSIL similar to this:
call Foo::op_Equality(Foo, Foo)
If it doesn't find an overload, it will emit the regular comparison opcode:
And that's the problem. Because operators are static, there are no virtual calls to exploit - if your type doesn't define an overload at compile-time, you don't get a chance to "add" one at run-time and let late-binding find it. Same reason we don't mock static or non-virtual calls in NMock.