我有一个相当学术的问题:为什么技术上不可能使用以下代码?
// abstractions
public record MappingRequest<TContract, TEntity>(TContract Contract, TEntity Entity);
public interface IMapper<TResult, TContract, TEntity>
{
TResult Map(MappingRequest<TContract, TEntity> request);
}
// more readable abstraction
public interface ILocationMapper : IMapper<LocationResult, LocationContract, LocationEntity>
{
}
// concrete
public record LocationResult;
public record LocationContract;
public record LocationEntity;
public record LocationRequest(LocationContract Contract, LocationEntity Entity) : MappingRequest<LocationContract, LocationEntity>(Contract, Entity);
public class LocationMapper : ILocationMapper
{
public LocationResult Map(LocationRequest request)
{
return new LocationResult();
}
}
这给了我以下编译器错误:
Error CS0535 : 'LocationMapper' does not implement interface member 'IMapper<LocationResult, LocationContract, LocationEntity>.Map(MappingRequest<LocationContract, LocationEntity>)'
为什么编译器不能“推断”(不完全确定这是否是正确的术语)
LocationRequest
继承自MappingRequest
?
谢谢你的解释🙏🏻
您的
LocationMapper.Map
方法当前接受 LocationRequest
,但 IMapper<LocationResult, LocationContract, LocationEntity>
的任何实现都必须实现接受 any
Map
(而不仅仅是 MappingRequest<TContract, TEntity>
)的 LocationRequest
方法。
你的代码很简单,但想象一下
LocationRequest
有一个属性 Foo
:
public record LocationRequest(LocationContract Contract, LocationEntity Entity)
: MappingRequest<LocationContract, LocationEntity>(Contract, Entity)
{
public string Foo { get; }
}
你的方法尝试使用该属性:
public class LocationMapper : ILocationMapper
{
public LocationResult Map(LocationRequest request)
{
Console.WriteLine(request.Foo);
return new LocationResult();
}
}
现在,如果您尝试将其称为
IMapper<LocationResult, LocationContract, LocationEntity>
,并使用另一个 MappingRequest<TContract, TEntity>
,我们就会遇到问题,因为没有 foo 属性。
例如
var request = new MappingRequest<TContract, TEntity>(default, default);
IMapper<LocationResult, LocationContract, LocationEntity> mapper = new LocationMapper();
mapper.Map(request); // We don't have any Foo to use !!
问题在于
LocationRequest
不是 MappingRequest<LocationContract, LocationEntity>
的简化别名,它是完全不同的类型。
如果冗长对您来说是个问题,那么您可以像这样为您的类型添加别名:
using LocationRequest = MappingRequest<LocationContract, LocationEntity>;