我想创建一个指向静态函数的委托...静态函数有第二个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'
感谢大家的回答,我已经发现这甚至不是协方差/逆转问题
答案 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
。