如何简化泛型方法的调用,我创建了在项目的不同层中从一种类型转换为另一种类型

时间:2013-02-13 07:46:30

标签: c# generics

我希望第二个调用样式应该类似于第一个调用样式。请参阅我的代码中的详细信息。任何帮助都非常感谢。

这是我正在使用的代码。

//调用第一种方法的风格

            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
    {

    }

3 个答案:

答案 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);