委托参数中的Co(ntra)方差

时间:2011-11-03 15:02:42

标签: c# parameters delegates covariance

我想创建一个指向静态函数的委托...静态函数有第二个Flight类型的参数,Flight类实现ITravelObject接口,第二个委托参数需要这个接口。

以下代码不起作用。这是为什么?还有其他可能的实施吗?

namespace CovarianceContravarianceTest
{

    public class Data {}

    public interface ITravelObject
    {
        int ID { get; set; }
    }

    public abstract class BaseObject {}

    public class Flight : BaseObject, ITravelObject
    {
        int ITravelObject.ID {get;set;}
    }

    public static class LetService
    {
        public static void DoSomething(Data da, Flight let) {}
    }

    public delegate void TravelServiceMethodDelegate(Data dataAccess,ITravelObject     travelObject);

    class Program
    {
        static void Main(string[] args)
        {
            TravelServiceMethodDelegate test = new TravelServiceMethodDelegate(LetService.DoSomething);
        }
    }

}

这会导致错误

'DoSomething'没有超载匹配委托'CovarianceContravarianceTest.TravelServiceMethodDelegate'

感谢大家的回答,我已经发现这甚至不是协方差/逆转问题

3 个答案:

答案 0 :(得分:2)

您正在尝试插入此方法

public static void DoSomething(Data da, Flight let) {} 

加入此代表

var test = new TravelServiceMethodDelegate(LetService.DoSomething);

这不起作用。为什么?请考虑以下代码:

class CarRide : ITravelObject { }

void GoForACarRide(TravelServiceMethodDelegate travelService) {
    travelService.Invoke(someData, new CarRide());
}

这是编译,因为CarRide实现了ITravelObject

但是,如果我致电GoForACarRide(test),它会中断,因为test指向DoSomething,期望Flight

答案 1 :(得分:1)

您的代码不起作用,因为它不安全。您正在尝试创建声明其接受任何ITravelObject的委托,但它实际上仅适用于Flight。这是不安全的,所以不允许这样做。

但是,它会反过来发挥作用。此代码编译:

public delegate void TravelServiceMethodDelegate(Data dataAccess, Flight travelObject);

…

var test = new TravelServiceMethodDelegate(LetService.DoSomething);

答案 2 :(得分:1)

如果可以,你可以这样做:

namespace CovarianceContravarianceTest
{
    public interface ITravelObject { }

    public class Flight :  ITravelObject
    {
        public void Fly() { }
    }

    public class Cruise :  ITravelObject
    {
        public void Sail() { }
    }

    public static class LetService
    {
        public static void GoFlying(Flight flight) 
        {
            flight.Fly();
        }

        public static void GoSailing(Cruise cruise)
        {
            cruise.Sail();
        }  
    }

    public delegate void TravelServiceMethodDelegate(ITravelObject travelObject);

    class Program
    {
        static void Main(string[] args)
        {
            var test = new TravelServiceMethodDelegate(LetService.GoFlying);

            test(new Cruise());
        }
    }
}

cruise传递给GoFlying()显然无效。 Cruise不是Flight