B
Ben Voigt
I've extended the article "Covariance and Contravariance in Delegates" from
the C# Programmers' Guide, and it seems contravariance of delegates is
implemented wrong.
Lambda calculus states that Handler2Method is a subtype of HandlerMethod...
why can't I convert? However the last line does work, but I'm not wanting
to create new delegate objects. I'm actually implementing contravariant
events, and I'm scared about my remove implementation. In
event BaseInterface.baseEvent {
add { derivedEvent += new DerivedDelegate(value); } // add a new
handler, that's ok
remove { derivedEvent -= new DerivedDelegate(value); } // I don't want
to remove a new handler, I want to remove the one I added on the line above!
}
Is removal going to work, or have I created a "new" object that won't match
the existing one????
HELP!
class Mammals
{
}
class Dogs : Mammals
{
}
class Program
{
public delegate void HandlerMethod(Dogs sampleDog);
public delegate void Handler2Method(Mammals sample);
public static void FirstHandler(Mammals elephant)
{
}
public static void SecondHandler(Dogs sheepDog)
{
}
static void Main(string[] args)
{
// Contravariance permits this delegate.
HandlerMethod handler1 = FirstHandler;
HandlerMethod handler2 = SecondHandler;
Handler2Method handler3 = FirstHandler; // ok
HandlerMethod handler4 = handler3; // error CS0029: Cannot
implicitly convert type 'Program.Handler2Method' to 'Program.HandlerMethod'
HandlerMethod handler5 = (HandlerMethod)handler3; // error CS0030:
Cannot convert type 'Program.Handler2Method' to 'Program.HandlerMethod'
HandlerMethod handler6 = new HandlerMethod(handler3); // ok
}
}
the C# Programmers' Guide, and it seems contravariance of delegates is
implemented wrong.
Lambda calculus states that Handler2Method is a subtype of HandlerMethod...
why can't I convert? However the last line does work, but I'm not wanting
to create new delegate objects. I'm actually implementing contravariant
events, and I'm scared about my remove implementation. In
event BaseInterface.baseEvent {
add { derivedEvent += new DerivedDelegate(value); } // add a new
handler, that's ok
remove { derivedEvent -= new DerivedDelegate(value); } // I don't want
to remove a new handler, I want to remove the one I added on the line above!
}
Is removal going to work, or have I created a "new" object that won't match
the existing one????
HELP!
class Mammals
{
}
class Dogs : Mammals
{
}
class Program
{
public delegate void HandlerMethod(Dogs sampleDog);
public delegate void Handler2Method(Mammals sample);
public static void FirstHandler(Mammals elephant)
{
}
public static void SecondHandler(Dogs sheepDog)
{
}
static void Main(string[] args)
{
// Contravariance permits this delegate.
HandlerMethod handler1 = FirstHandler;
HandlerMethod handler2 = SecondHandler;
Handler2Method handler3 = FirstHandler; // ok
HandlerMethod handler4 = handler3; // error CS0029: Cannot
implicitly convert type 'Program.Handler2Method' to 'Program.HandlerMethod'
HandlerMethod handler5 = (HandlerMethod)handler3; // error CS0030:
Cannot convert type 'Program.Handler2Method' to 'Program.HandlerMethod'
HandlerMethod handler6 = new HandlerMethod(handler3); // ok
}
}