是否可以修改此扩展方法以获得更清晰的语法?

Can this extensionmethod be modified to have a cleaner syntax?

我的域模型类继承自:

BaseModel<T>

例如:

public partial class WarehouseType : BaseModel<WarehouseType>
{}

我正在尝试将扩展方法添加到 BaseModel 中:

public static class BaseModelExtensionMethods
{
    public static TDto ToDto<TDto, TModel>(this Model.SharedKernel.BaseModel<TModel> model)
    {
        return Globals.mapper.Map<TDto>(model);
    }
}

这就是我的使用方式:

Model.Inventory.WarehouseType warehouseType = new Model.Inventory.WarehouseType();

warehouseType.ToDto<V1.Messages.WarehouseTypeDto, Model.Inventory.WarehouseType>();

如上面代码所示,我需要将两种类型(TDto,TModel)传递给ToDto<> extensionmethod。

我想知道是否可以以不需要将 TModel 传递给 ToDto<> 并获取 [=16= 的方式修改 ToDto<> 语法] 例如根据调用扩展方法的对象类型在方法内部键入?做这样的事情有什么解决方法或魔法吗?我需要这个,这样代码会变得更干净,更容易使用。

我正在寻找的理想语法如下:

warehouseType.ToDto<V1.Messages.WarehouseTypeDto>();

你可以试试这个

public class BaseModel { }
public class BaseModel<T> : BaseModel { }

然后为 BaseModel 创建扩展方法

public static class BaseModelExtensionMethods
{
public static TDto ToDto<TDto>(this Model.SharedKernel.BaseModel model)
{
    return Globals.mapper.Map<TDto>(model);
}
}

C# 不允许对泛型类型或方法的类型参数进行部分求值(或推断)(您可以切换到 F#,它可以)。所以你有几个选择 - 如果你愿意创建一个中间体 class 来记住推断的类型,你可以选择分步泛化,或者创建特化,或者你可以不推断任何类型。

要分步进行,您必须将 ToDto 方法分成两部分,并使用中间 class 来携带推断类型。调用此 class Toer(另请参阅 this answer):

public class Toer<TModel> {
    Model.SharedKernel.BaseModel<TModel> model;

    public Toer(Model.SharedKernel.BaseModel<TModel> model) => this.model = model;
    public TDto Dto<TDto>() => Globals.mapper.Map<TDto>(model);
}

现在,您创建一个 returns 一个 Toer 对象的扩展方法:

public static Toer<TModel> To<TModel>(this Model.SharedKernel.BaseModel<TModel> model) => new Toer<TModel>(model);

现在您可以替换旧代码:

var wtDto = warehouseType.ToDto<WarehouseTypeDto, Model.Inventory.WarehouseType>();

使用新代码:

var wtDto = warehouseType.To().Dto<WarehouseTypeDto>();

或者,您可以为每个可能的项目创建专业化 TModel:

public static TDto ToDto<TDto>(this Model.SharedKernel.BaseModel<Model.Inventory.WarehouseType> model) => Globals.mapper.Map<TDto>(model);

您可以根据需要使用它。

最后,您可以将映射预编码到相应的 DTO 类型的特化,并使用它们:

public static WarehouseTypeDto ToDto(this Model.SharedKernel.BaseModel<Model.Inventory.WarehouseType> model) => Globals.mapper.Map<WarehouseTypeDto>(model);