C# 是否可以修改此extensionmethod,使其具有更清晰的语法?

C# 是否可以修改此extensionmethod,使其具有更清晰的语法?,c#,generics,extension-methods,C#,Generics,Extension Methods,我的域模型类继承自: BaseModel<T> 你可以试试这个 public class BaseModel { } public class BaseModel<T> : BaseModel { } 公共类基类{} 公共类BaseModel:BaseModel{} 然后为BaseModel创建扩展方法 public static class BaseModelExtensionMethods { public static TDto ToDto<TDto&g

我的域模型类继承自:

BaseModel<T>
你可以试试这个

public class BaseModel { }
public class BaseModel<T> : BaseModel { }
公共类基类{}
公共类BaseModel:BaseModel{}
然后为BaseModel创建扩展方法

public static class BaseModelExtensionMethods
{
public static TDto ToDto<TDto>(this Model.SharedKernel.BaseModel model)
{
    return Globals.mapper.Map<TDto>(model);
}
}
公共静态类BaseModelExtensionMethods
{
公共静态TDto ToDto(this Model.SharedKernel.BaseModel模型)
{
返回Globals.mapper.Map(模型);
}
}
您可以试试这个

public class BaseModel { }
public class BaseModel<T> : BaseModel { }
公共类基类{}
公共类BaseModel:BaseModel{}
然后为BaseModel创建扩展方法

public static class BaseModelExtensionMethods
{
public static TDto ToDto<TDto>(this Model.SharedKernel.BaseModel model)
{
    return Globals.mapper.Map<TDto>(model);
}
}
公共静态类BaseModelExtensionMethods
{
公共静态TDto ToDto(this Model.SharedKernel.BaseModel模型)
{
返回Globals.mapper.Map(模型);
}
}
C#不允许对泛型类型或方法的类型参数进行部分求值(或推断)(您可以切换到F#,它允许)。因此,您有一些选择—如果您愿意创建一个中间类来记住推断的类型,或者创建专门化,或者您可以不推断任何类型,那么您可以选择分步骤进行泛化

要分步执行,必须将
ToDto
方法分为两部分,并使用中间类携带推断类型。将此类称为Toer(另请参见):

现在,您可以替换旧代码:

var wtDto = warehouseType.ToDto<WarehouseTypeDto, Model.Inventory.WarehouseType>();
您可以根据需要使用它

最后,您可以使用专门化将映射预编码到相应的DTO类型,并使用这些专门化:

public static WarehouseTypeDto ToDto(this Model.SharedKernel.BaseModel<Model.Inventory.WarehouseType> model) => Globals.mapper.Map<WarehouseTypeDto>(model);
公共静态仓库类型dto ToDto(this Model.SharedKernel.BaseModel Model)=>Globals.mapper.Map(Model);
C#不允许对泛型类型或方法的类型参数进行部分求值(或推断)(您可以切换到F#,它允许)。因此,您有一些选择—如果您愿意创建一个中间类来记住推断的类型,或者创建专门化,或者您可以不推断任何类型,那么您可以选择分步骤进行泛化

要分步执行,必须将
ToDto
方法分为两部分,并使用中间类携带推断类型。将此类称为Toer(另请参见):

现在,您可以替换旧代码:

var wtDto = warehouseType.ToDto<WarehouseTypeDto, Model.Inventory.WarehouseType>();
您可以根据需要使用它

最后,您可以使用专门化将映射预编码到相应的DTO类型,并使用这些专门化:

public static WarehouseTypeDto ToDto(this Model.SharedKernel.BaseModel<Model.Inventory.WarehouseType> model) => Globals.mapper.Map<WarehouseTypeDto>(model);
公共静态仓库类型dto ToDto(this Model.SharedKernel.BaseModel Model)=>Globals.mapper.Map(Model);

您可以添加一个伪参数来推断
TDto
类型,因为您必须推断所有类型或显式指定所有类型
public static TDto ToDto(this Model.SharedKernel.BaseModel Model,TDto dummyToInferType)
或者您可以在
BaseModel
@juharr上创建
ToDto
一个方法,我看不出应该如何调用您提供的方法。此外,它不能像我问题中的理想syntaxt那样调用。@juharr BaseModel在我的域模型层中,我正在尝试将其扩展到ESB层中,ESB层位于域模型层之上,DTO位于ESB层中,因此我无法从域模型层引用ESB层。它是否需要是一种扩展方法?您可以将您的方法添加到BaseModel吗?如果要将代码放在不同的文件中,可以使用分部类。@Alex TinLe它不必是extensionmethod,但我希望它是extensionmethod。由于BaseModel位于域模型层内,如果我将此方法添加到BaseModel类中,那么我将需要将IMapper注入域模型层,并且我更喜欢当前有点难以使用的syntaxt而不是这种DI方法。我知道部分类,并且在域模型层中有它们,但这不是我想要做的。您可以添加一个伪参数来推断
TDto
类型,因为您必须推断所有类型或显式指定所有类型
public static TDto ToDto(this Model.SharedKernel.BaseModel Model,TDto dummyToInferType)
或者您可以在
BaseModel
@juharr上创建
ToDto
一个方法,我看不出应该如何调用您提供的方法。此外,它不能像我问题中的理想syntaxt那样调用。@juharr BaseModel在我的域模型层中,我正在尝试将其扩展到ESB层中,ESB层位于域模型层之上,DTO位于ESB层中,因此我无法从域模型层引用ESB层。它是否需要是一种扩展方法?您可以将您的方法添加到BaseModel吗?如果要将代码放在不同的文件中,可以使用分部类。@Alex TinLe它不必是extensionmethod,但我希望它是extensionmethod。由于BaseModel位于域模型层内,如果我将此方法添加到BaseModel类中,那么我将需要将IMapper注入域模型层,并且我更喜欢当前有点难以使用的syntaxt而不是这种DI方法。我知道部分类,我在域模型层中有它们,但这不是我想做的。谢谢你,先生,我从你的回答中学到了很多,我真的很感激。但是@Alex TinLe发布的答案给了我一个理想的语法,我正在寻找它,对代码的复杂度和修改最少,也不需要像你提到的那样为创建专门化而过度劳累。所以我将把他的答案标记为被接受的答案。谢谢你,先生,我从你的答案中学到了很多,我真的很感激。但是@Alex TinLe发布的答案给了我一个理想的语法,我正在寻找它,对代码的复杂度和修改最少,也不需要像你提到的那样为创建专门化而过度劳累。所以我要把他的答案标记为被接受的答案。谢谢你,亚历克斯。它非常简单,易于使用。:)很高兴这有帮助。:)既然
Map
必须采用
object
参数,您就不能让
ToDto
采用
object
参数吗
var wtDto = warehouseType.ToDto<WarehouseTypeDto, Model.Inventory.WarehouseType>();
var wtDto = warehouseType.To().Dto<WarehouseTypeDto>();
public static TDto ToDto<TDto>(this Model.SharedKernel.BaseModel<Model.Inventory.WarehouseType> model) => Globals.mapper.Map<TDto>(model);
public static WarehouseTypeDto ToDto(this Model.SharedKernel.BaseModel<Model.Inventory.WarehouseType> model) => Globals.mapper.Map<WarehouseTypeDto>(model);