gpt4 book ai didi

c# - 通用接口(interface),通用接口(interface)与泛型

转载 作者:太空宇宙 更新时间:2023-11-03 19:59:02 25 4
gpt4 key购买 nike

我的问题中有很多泛型,我希望它仍然是可以理解的...

我有以下接口(interface):

public interface ICommandBus
{
TResult Publish<TCommand, TResult>(TCommand command)
where TResult : ICommandResult
where TCommand : ICommand<TResult>;
}

public interface ICommand<T>
where T : ICommandResult
{ }

public interface ICommandResult
{
bool Success { get; }
}

我想以这种方式使用他们的实现(我省略了 CommandBus,它对这个问题没有用,但你可以找到它 here ):

public class CreateItemCommand: ICommand<CreateItemResult>
{
public string Name { get; private set; }
}
public class CreateItemResult: ICommandResult
{
public bool Success { get; private set; }
}

var command = new CreateItemCommand();
var result = commandBus.Publish(command); //Error here

我遇到了错误:The type arguments cannot be inferred from the usage .我用 in 做了一些尝试和 out修改器没有成功...

如何调用我的 Publish方法,无需像这样指定参数类型:

var result = commandBus.Publish<CreateItemCommand, CreateItemResult>(command); //Works, but ugly...

编辑:卢卡斯回答的更新

Lucas 解决方案应该有效,但我仍然必须将 where TResult : ICommandResult避免错误的约束 There is no boxing conversion or type parameter conversion from 'TResult' to 'Core.Command.ICommandResult' .

我在继承方面也有很大的问题,假设我有以下抽象 CommandObserver:

public abstract class NotificationObserver<TResult> : ICommandObserver<TResult>
where TResult : ICommandResult
{
protected virtual bool IsEnable(ICommand<TResult> command, TResult result)
{
return true;
}
}

它的实现

public class CreateItemObserver : NotificationObserver<CreateItemResult>
{
protected override bool IsEnable(CreateItemCommand command, CreateItemResult result)
{
return !String.IsNullOrEmpty(command.Name);
}
}

这是行不通的,因为实现并没有真正覆盖虚拟方法(不是相同的签名:ICommand<TResult> != CreateItemCommand)。

如果我确实保留了正确的签名,我将无法在没有丑陋的实现的情况下使用 CreateItemCommand 属性...

最佳答案

您可以像这样轻松重写您的界面以摆脱 TCommand参数:

public interface ICommandBus
{
TResult Publish<TResult>(ICommand<TResult> command)
where TResult : ICommandResult;
}

请注意,您还可以删除 where TResult : ICommandResult ,因为此约束与 ICommand<TResult> 中的定义是多余的:

public interface ICommandBus
{
TResult Publish<TResult>(ICommand<TResult> command);
}

我想 C# 拒绝在您的案例中推断类型参数的原因是 TCommand可以实现 ICommand<T>多次,像这样:

public class SomeCommand : ICommand<Foo>, ICommand<Bar>
{
// ...
}

关于c# - 通用接口(interface),通用接口(interface)与泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30442141/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com