是否可以修改此扩展方法以获得更清晰的语法?
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);
我的域模型类继承自:
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);