viernes, diciembre 03, 2004

Covariance and Contravariance

Support for delegates Contravariance/Contravariance support is now in Mono SVN repository.

In C# world, delegates are constructions designed to save a function; in the C world, this is similar to function pointers. Delegates offer some advntages over C function pointers, as compile and run type checks, additional properties, and they also add clearness in code.

Currently, the delegates are defined just as the following example:

public delegate void MethodHandler (string msg);

In this case, MethodHandler will act as a pointer to methods with the signature defined by itself; this is, methods with void as return value, and string as a unique paratemer. A method such void SomeMethod (string msg) would be valid, but a one like void OtherMethod (string msg, string msg2) or int AnotherOne (string msg) wouldn't.

The problem here is that the methods passed to the delegates must have the exact signature defined by it. Here is where Contravariance and Covariance come to scene.

Having something like:

class A {}
class B : A {}

delegate A MethodHandler () { // Do something }

It would be nice to have the chance to pass not only methods like A MyMethod (), but also B MyOtherMethod. This would be possible because Be is just only a specialization of class A, which is the return value defined by delegate MethodHandler. So, returning B instead of A could be done just because B is in fact, a A class, bust maybe with more methods, more properties, etc.

With the Mono 1.x series,a dn also with MS .Net 1.0, that wouldn't be possible. Mo more: .Net 2.0 (which is in state of beta) and current Mono development branch support it.

Again, having code like this:

class A {}
class B : A {}
delegate void MethodHandler (B b);

Methods in the form: void SomeMethod (A a) and also void OtherMethod (B b) could be passed. Why? it's because B instances could be casted to A, so, if a delegate is called, it will receive a B instance, which will cast to A for the void OtherMethod (B b).

Just as above, this is not possible with Mono 1.x/.Net 1.0, but it is avalaible with .Net 2.0 and Mono development branch.

No hay comentarios.: