gpt4 book ai didi

c# - 使用协方差和多个泛型参数时转换为基础接口(interface)

转载 作者:行者123 更新时间:2023-11-30 21:54:13 25 4
gpt4 key购买 nike

我试图让所有这些映射器类有一个共同的基础:

// base
class BaseInput { public string BaseInputValue { get; set; } }
class BaseOutput { public string BaseOutputValue { get; set; } }

interface IMapper<InputType, out OutputType>
where InputType : BaseInput
where OutputType : BaseOutput
{
OutputType Map(InputType input);
}

// example implementation
class Input : BaseInput { public string InputValue { get; set; } }
class Output : BaseOutput { public string OutputValue { get; set; } }

class MyMapper : IMapper<Input, Output>
{
public Output Map(Input input)
{
// custom mapping done here to Output
return new Output { /* mapping */ };
}
}

创建这些映射器中的一个新映射器并将其分配给基础编译器的代码可以正常编译:

var myBaseMapper = (IMapper<BaseInput, BaseOutput>) new MyMapper();

但是我得到一个运行时错误:

Unable to cast object of type 'MyMapper' to type 'IMapper`2[UserQuery+BaseInput,UserQuery+BaseOutput]'.

如果我减少 IMapperIMapper<out OutputType>它工作正常,但这需要在 MyMapper.Map 中进行转换,这在每个映射器类中都必须做,这有点烦人。此外,这让我失去了决定将哪个 Mapper 用于什么的信息 BaseInput所以我必须在别处定义它。

在 C# 中这样做是不可能的,还是有一种方法可以做类似的事情?否则,我将不得不重新考虑我的设计。

最佳答案

你不能这样做,因为它没有意义,你的界面在 InputType 中是逆变的参数(或者更确切地说,如果您将 in 关键字添加到该参数)。要了解为什么这没有意义,让我们看看您的示例:

你想要一个 IMapper<Input, Output> 的实现可分配给 IMapper<BaseInput, BaseOutput> .假设我们创建了一些新的子类 BaseInput ,我们称之为 MoreInput :

class MoreInput : BaseInput
{
public string LotsOfInput { get; set; }
}

好吧,现在假设我们有一个方法,其主体看起来像这样(而且您想要的确实有效):

IMapper<BaseInput, BaseOutput> mapper = new MyMapper();
mapper.Map( new MoreInput() );

好吧,此时没有任何问题:IMapper<BaseInput, BaseOutput>有一个 Map接受 BaseInput 的方法作为其参数和 MoreInput 是一个 BaseInput , 所以我们调用 Map有效。

除了它不是,因为 Map我们真正调用的方法需要一个Input作为它的论点和MoreInput不是 Input .我们打破了类型系统。

这就是编译器在不允许您隐式进行该赋值时告诉您的内容:该转换不安全。编译器不能保证你期望的类型就是你得到的类型。

关于c# - 使用协方差和多个泛型参数时转换为基础接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33243300/

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