C# 转换泛型类型时出错

C# 转换泛型类型时出错,c#,generics,C#,Generics,我有一个方法ExecCommand,它将Command作为参数。但当我尝试传递带有CommandResult派生泛型类型的命令时,它无法生成: class Program { class CommandResult { } class Command<TResult> where TResult : CommandResult, new() { internal virtual TResult ParseReply(objec

我有一个方法
ExecCommand
,它将
Command
作为参数。但当我尝试传递带有
CommandResult
派生泛型类型的命令时,它无法生成:

class Program
{
    class CommandResult
    {
    }

    class Command<TResult> where TResult : CommandResult, new()
    {
        internal virtual TResult ParseReply(object reply)
        {
            return new TResult();
        }
        public Action<TResult> CommandCompleteCallback = null;
    }

    class CommandA : Command<CommandResult>
    {
    }

    class CommandResultForB : CommandResult
    {
    }

    class CommandB : Command<CommandResultForB>
    {
        internal override CommandResultForB ParseReply(object reply)
        {
            return new CommandResultForB();
        }
    }

    static Queue<Command<CommandResult>> commandQueue = new Queue<Command<CommandResult>>();

    static void ThreadLoop()
    {
        // This threadloop transmits the first command on the queue to external library when executeNextCommand is set (it's using Peek, so the command stays in the queue until the external library calls OnCommandCompleteResponse()
    }
    static void OnCommandCompleteRespose(object reply)
    {
        // called from external library when command is complete
        lock (commandQueue)
        {
            var command = commandQueue.Dequeue();
            if (command.CommandCompleteCallback != null)
                command.CommandCompleteCallback(command.ParseReply(reply));
        }
    }
    static void ExecCommand(Command<CommandResult> command)
    {
        lock (commandQueue)
        {
            commandQueue.Enqueue(command);
            if (commandQueue.Count == 1)
                executeNextCommand.Set();
        }
    }

    static void Main(string[] args)
    {
        ExecCommand(new CommandA());
        ExecCommand(new CommandB()); // <-- this is the offending line
    }
}
类程序
{
类命令结果
{
}
类命令,其中TResult:CommandResult,new()
{
内部虚拟树结果ParseReply(对象回复)
{
返回新的TResult();
}
公共操作命令CompleteCallback=null;
}
类CommandA:Command
{
}
类CommandResultForB:CommandResult
{
}
类CommandB:Command
{
内部重写命令ResultForb ParseReply(对象回复)
{
返回新的CommandResultForB();
}
}
静态队列命令队列=新队列();
静态void ThreadLoop()
{
//设置ExecuteExtCommand时,此threadloop将队列上的第一个命令传输到外部库(它使用Peek,因此该命令将保留在队列中,直到外部库调用OnCommand和CompleteResponse()
}
CommandCompleteRespose上的静态void(对象回复)
{
//命令完成时从外部库调用
锁(命令队列)
{
var command=commandQueue.Dequeue();
if(command.CommandCompleteCallback!=null)
command.CommandCompleteCallback(command.ParseReply(reply));
}
}
静态void ExecCommand(命令命令)
{
锁(命令队列)
{
命令队列。排队(命令);
if(commandQueue.Count==1)
executeNextCommand.Set();
}
}
静态void Main(字符串[]参数)
{
ExecCommand(newcommanda());

ExecCommand(new CommandB());//如果要使用
CommandB
类型的实例调用
ExecuteCommand()
,并且仍然尽可能通用,请使用以下命令:

static void ExecCommand<TResult>(Command<TResult> command) 
    where TResult : CommandResult, new()
{
    TResult res = command.ParseReply(null);
}
static void ExecCommand(命令)
其中TResult:CommandResult,new()
{
TResult res=command.ParseReply(null);
}

注意:这是对原始问题的回答。这可能有助于理解问题的这一部分,也可能有助于其他人。

此异常的原因是默认情况下,通用参数不是:

在.net 3.5中添加了对此的支持,但您需要通过接口和关键字来定义它:


这只是将错误移动到inside ExecCommand。我将命令排队到一个
队列
,这将导致相同的错误。那么,您在那里也有相同的问题。您可以做的是将结果强制转换为CommandResult。我将对此进行编辑。这太糟糕了,因为command还有一个通用回调参数然后将<代码>命令结果< /C>作为参数而不是正确的类型…因为泛型不是C++模板。
interface ICommand<out TResult> where TResult : CommandResult, new()
{
   TResult ParseReply(object reply);
}


class Command<TResult> : ICommand<TResult> where TResult 
                       : CommandResult, new()
{}
static void ExecCommand(ICommand<CommandResult> command){}
static void Main(string[] args)
{
    ExecCommand(new CommandA());
    ExecCommand(new CommandB()); // <-- works now           
}