C#委托函数委托,没有返回值和一个允许子类型类(作为参数)的参数



我正在寻找一个委托的委托,该委托封装了一种返回不值的方法并采用一个参数,例如 action<t> 确实如此,但不幸的是,该委托与将儿童类型作为参数的方法不匹配...

这就是我要做的:

public class BaseType
{
    public BaseType()
    {
    }
}
public class ChildType : BaseType
{
    public ChildType()
    {
    }
}
public class Test
{
public delegate void CallBackHandler(BaseType p);
    public Test()
    {
        CallBackHandler clbk1 = callBackA;
        CallBackHandler clbk2 = callBackB;   //That line does not compile
                                             //->'No overload for 'callBackB' matches delegate 'Test.CallBackHandler'
    }
    private void callBackA(BaseType p)
    {
    }
    private void callBackB(ChildType p)
    {
    }
}

我读到了有关协方差,违反等级等...我知道它涉及超级类型的铸造,但我对这一切有些困惑...

我应该使用哪个代表来使我的代码工作?

这是创建强大打字以解决的经典类型安全问题。

这是一个示例

abstract class Vehicle
{
    public virtual void MethodSlot1_StartEngine() { }
    public virtual void MethodSlot2_StopEngine() { }
}
class Car : Vehicle
{
    public virtual void MethodSlot3_OpenGasTank() { }
}
class NuclearSubmarine : Vehicle
{
    public virtual void MethodSlot3_FireAllNuclearMissiles() { }
}
class VehicleUser
{
    public delegate void OpenGasTankMethod(Car car);
    public void OpenGasTank(Vehicle vehicle, OpenGasTankMethod method)
    {
        //it's stopping you here from firing all nuclear weapons
        //by mistaking your car's gas tank for the armageddon switch
        method(vehicle); 
    }
}

编译器发出虚拟方法时,只需将索引编译到查找表中即可。如果您只能因为它们都是车辆而需要汽车的核武器,那么您可以认为您正在调用汽车方法(例如打开汽油箱(,而实际上您只是在做降期一系列游戏是现实。

回答您的评论,这应该使您入门:

class Blah
{
    private List<Action<object>> _handlers = new List<Action<object>>();
    public void AddListener<T>(Action<T> handler)
    {
        //graceful type checking code goes in here somewhere
        _handlers.Add(o => handler((T) o));
    }
    void RaiseEvent(object eventArgs)
    {
        foreach (var handler in _handlers) handler(eventArgs);
    }
}

您不能这样做,因为它不安全。如果允许您这样做:

class OtherChild : BaseType { }
CallBackHandler clbk2 = callBackB;
clbk2(new OtherChild());

并将OtherChild的实例传递给需要ChildType实例的委托。请注意,以下内容是安全且编译的:

public delegate void CallBackHandler(ChildType p);
CallBackHandler clbk1 = callBackA;
CallBackHandler clbk2 = callBackB;

将代表称为

public delegate void CallBackHandler(ChildType p)

如果处理程序可以接受并且应该在BaseType的实例上采取行动,那么如果您在新类NewChildType的情况下通过会发生什么?没人知道,这就是您不能在这里的原因。

相关内容

  • 没有找到相关文章

最新更新