无法将派生类传递给接受通用基类的方法

时间:2016-09-13 09:54:23

标签: c#

从广义上讲,我有以下代码......

using System;

public interface ICommand<in TArgs>
    where TArgs : BaseArgs
{
    void Execute();
    void Execute(TArgs args);
}

public class BaseArgs
{ }

public abstract class BaseCommand<TArgs> : ICommand<TArgs>
    where TArgs : BaseArgs
{
    public void Execute()
    {
        var args = this.CreateArgs();
        this.Execute(args);
    }

    public void Execute(TArgs args)
    {
        this.GetData(args);
    }

    protected abstract void GetData(TArgs args);
    protected abstract TArgs CreateArgs();
}

public class ActualArgs : BaseArgs
{ }

public class ActualCommand : BaseCommand<ActualArgs>
{
    protected override void GetData(ActualArgs args)
    {
        var messenger = new Messenger(this.Execute);
        var m2 = new Messenger2(this);
    }

    protected override ActualArgs CreateArgs()
    {
        return new ActualArgs();
    }
}

public class Messenger
{
    public Messenger(Action caller)
    {
        caller();
    }
}

public class Messenger2
{
    public Messenger2(BaseCommand<BaseArgs> caller)
    {
        caller.Execute();
    }
}

理想情况下,我想使用Messenger2,但ActualCommand中的一行抱怨它无法将ActualCommand<ActualArgs>投放到BaseCommand<BaseArgs>,我真的不会声明{ {1}}为

Messenger2

1 个答案:

答案 0 :(得分:3)

这不起作用有两个原因:

  1. 只能使用通用接口协变(或逆变)。您的参数是抽象基类,而不是接口。
  2. 您的界面不是(也不可能)是协变的。
  3. 假设这实际编译了 - 你可以这样做:

    BaseCommand<BaseArgs> command = new ActualCommand();
    
    command.Execute(new SomeOtherArgsDerivedFromBaseArgs());
    

    这个必须给你一些例外,因为ActualCommand不知道如何处理除了ActualArgs之外的任何事情。