Why not: Covariant Parameter- and Contravariant Return-Types in Delegate-Methods?

  • Thread starter Thread starter Matz
  • Start date Start date
M

Matz

Hello,
based on the CSharp 2.0 Beta, it will be possible to have covariant
Returntypes and contravariant Parametertypes in Delegate-Methods. Can
someone explain me, why it´s not usefull (and maybe not possible?) to
have both for each types: contravariant Returntypes and covariant
Parametertypes?

thanks a lot
 
Matz said:
based on the CSharp 2.0 Beta, it will be possible to have covariant
Returntypes and contravariant Parametertypes in Delegate-Methods. Can
someone explain me, why it´s not usefull (and maybe not possible?) to
have both for each types: contravariant Returntypes and covariant
Parametertypes?

From what I remember, "co-variant" means "use a derived type instead of
a base type" and "contra-variant" means "use a base type instead of a
derived type". That makes sense for return types and parameters
respectively, as the caller doesn't need to know the difference - it's
still able to pass in something of the derived type, and be returned a
reference to an instance of the base type (as far as it's concerned).

A contravariant return type would mean that something declared in the
base type to return "string" could then return an instance of just
"object", and it could *require* a string when the previous parameter
was just object. So this call:

string x = foo.DoSomething (new object());

would fail in both the parameter and the return.

This is all based on my first sentence though, so if that's wrong the
rest will be too...
 
From what I remember, "co-variant" means "use a derived type instead of
a base type" and "contra-variant" means "use a base type instead of a
derived type".

That´s exactly the same I know about these things.
A contravariant return type would mean that something declared in the
base type to return "string" could then return an instance of just
"object", and it could *require* a string when the previous parameter
was just object. So this call:

string x = foo.DoSomething (new object());

would fail in both the parameter and the return.

I think the parameter would not fail because, every "string" is an
"object", too. The contravariant return-type would fail, because a
"object" is not always a "string" - a type-safe-failure.

This is just the expected behaviour in a situation where a class is
derived from a base class and a method has been overwritten. In C# 2.0
beta its still not allowed to have co- or contravariance in this
Derived-Class-Situation. But in delegates! Something like this is
possible:

[CoVariance in 2.0 Beta]
---------------------------------------------------------------
class base{}
class derived : base{}

public delegate base DelegateObject();

DelegateObject del = new DelegateObject(Method1);
del += new DelegateObject(Method2);

public static base Method1() {...}
public static derived Method2() {...}
---------------------------------------------------------------

[Contravariance in 2.0 Beta]
--------------------------------------------------------------
class base{}
class derived : base{}

public delegate void DelgateObject(derived aDerived);

DelegateObject del = new DelegateObject(Method1);
del += new DelegateObject(Method2);
del += new DelegateObject(Method3);

public static void Method1(derived aDer){...}
public static void Method2(base aBase){...}
public static void Method3(Object aObject){...}
----------------------------------------------------------------

I don´t understand, why in this special delegate-way, it´s not
possible to have covariant Parameters and contravariant return types?

many Greetings
Matz
 
Matz said:
That´s exactly the same I know about these things.


I think the parameter would not fail because, every "string" is an
"object", too.

That's just the point though - if the method is *expecting* a string
and you pass it an object, it's going to fail.
The contravariant return-type would fail, because a
"object" is not always a "string" - a type-safe-failure.

And that's exactly the same problem as with co-variant parameters.
This is just the expected behaviour in a situation where a class is
derived from a base class and a method has been overwritten. In C# 2.0
beta its still not allowed to have co- or contravariance in this
Derived-Class-Situation. But in delegates! Something like this is
possible:

I don´t understand, why in this special delegate-way, it´s not
possible to have covariant Parameters and contravariant return types?

For exactly the reasons I've given. You've accepted that contravariant
return types would lead to type safety failures, and the same is true
for covariant parameters.

To use my object/string example, if you've got a delegate

delegate string Foo (object o);

and you were able to instantiate it like this:

Foo f = new Foo (Bar);

where Bar is:

object Bar (string s)
{
return new object();
}

then call it like this:

// Perfectly legal by the declaration of Foo
string s = f(new object());

then Bar would get something *other* than a string as its parameter,
and even if it didn't, it would be trying to return a plain object when
the caller is expecting a string. Nastiness all round.
 
Back
Top