我希望第二个调用样式应该类似于第一个调用样式。请参阅我的代码中的详细信息。任何帮助都非常感谢。
这是我正在使用的代码。
//调用第一种方法的风格
var source = db.ThinkFeeds.Single(tf => tf.ID == 1);
var target = new MyProduct.UIEntities.ThinkFeed();
TypeConverter.ConvertBlToUi(source, target);
//调用第二种方法的风格。它真的是一种奇怪的召唤方式。
var source = MyProduct.UIEntities.Book.GetBookByID(1);
var target = new MyProduct.DTOEntities.Book();
TypeConverter.ConvertUiToDto<MyProduct.UIEntities.Book, MyProduct.DTOEntities.Book, Book>(source, target);
//第一种方法
public static void ConvertBlToUi<TBl, TUi>(TBl entitySource, TUi entityTarget)
{
}
//第二种方法
public static void ConvertUiToDto<TUi, TDto, TEntity>(TUi uiEntity, TDto dtoEntity)
where TDto : DTOEntities.MyProductDTO<TEntity, TDto>
where TEntity : EntityObject
{
}
答案 0 :(得分:3)
你做不到。 Generic Methods,输入推理:
编译器可以根据您传入的方法参数推断类型参数;它不能仅从约束或返回值推断类型参数。因此...
您展示的第一种风格是使用类型推断,但它只是一种方便的简写。有时(如此处)类型推断无法工作,因此您必须明确提供类型参数。
答案 1 :(得分:0)
TEntity
中的ConvertUiToDto
类型参数是阻止类型推断的参数,并强制您在调用此方法时明确指定所有类型参数。不幸的是,此类型参数用于在TDto
上添加类型约束:
where TDto : DTOEntities.LightsailDTO<TEntity, TDto>
只要此约束仍然存在,您就无法在调用TEntity
时从声明中删除ConvertUiToDto
并使用类型推断。
现在我的问题是:为什么LightsailDTO
需要TEntity
类型参数?不是DTO应该允许传输实体数据而不必暴露它们吗?
答案 2 :(得分:0)
我实际上问了一个类似的问题并自己提供了答案。
Is there a workaround to C# not being able to infer generic type arguments using type constraints?
基本上,你唯一的选择是两次传递DTO,让它分别推断每个泛型类型参数:
public static void ConvertUiToDto<TUi, TDto, TEntity>(TUi uiEntity, TDto dtoEntity, DTOEntities.MyProductDTO<TEntity, TDto> dtoEntity2)
where TDto : DTOEntities.MyProductDTO<TEntity, TDto>
where TEntity : EntityObject
{
}
并将其称为:
var source = MyProduct.UIEntities.Book.GetBookByID(1);
var target = new MyProduct.DTOEntities.Book();
TypeConverter.ConvertUiToDto(source, target, target);