通用映射方法无法转换为具体类型

时间:2013-08-14 13:57:17

标签: c# generics .net-4.5

我正在尝试创建一个通用映射函数,该函数将接受所有从NSReportBase继承的类型,然后新建相应的对象并返回它。到目前为止,我有以下内容:

internal static T BuildNamingStandardType<T>(DataRow dr) where T : NSReportBase, new()
{
    T newNamingStandardReport = null;

    if (typeof(T) is NSPipelineSystems)
        newNamingStandardReport = new NSPipelineSystems(dr["Column1"], dr["Column2"]);
    else if (typeof(T) is NSPipelineSegmentGroups)
        newNamingStandardReport = new NSPipelineSegmentGroups(dr["Column3"]);

    return newNamingStandardReport; 
}

但是,我收到的错误是每个具体类型都不能隐式转换为类型'T'。鉴于编译器知道T属于'NSReportBase'类型,我不确定我是否理解这个问题,更不用说如何修复它了。

编辑:我可能已经简化了示例。挑战在于构造函数实际上不带参数,而是DataRow中作为方法参数的不同数量和类型的列。我知道我可以多态地执行此操作,但我希望通过将此方法移动到相应的域对象中来避免将DataRow列名称暴露给我的业务逻辑。

3 个答案:

答案 0 :(得分:2)

只要您尝试实例化的类型具有默认构造函数,您就可以使用新约束。

where T : new()

那么你就可以

var instance = new T();

此错误还来自于编译器只知道T属于NSReportBase类型的事实,但是当使用T变为NSPipelineSystemsNSPipelineSegmentGroups并且您无法分配NSPipelineSystems时} NSPipelineSegmentGroups反之亦然,这就是你得到错误的原因。

如果你想解决,你必须改变

T newNamingStandardReport = null;

NSReportBase newNamingStandardReport = null;

并手动将返回值转换为(T)。

答案 1 :(得分:1)

  

鉴于编译器已知T为“NSReportBase”类型

编译器不知道。 C#语言没有定义编译器必须通过数据流跟踪派生类型(实际上禁止编译它)。人类可以看到这个事实,语言被定义为不会看到它(但像Resharper 这样的工具可以将其视为实用工具)。

解决方案:首先转换为object,然后转换为具体类型。这种方法对我来说仍然像个黑客。也许您应该首先评估是否应该使用泛型。泛型的目的是你的泛型方法不需要关注具体类型

答案 2 :(得分:0)

internal static T BuildNamingStandardType<T>(DataRow dr) where T : NSReportBase, new()
{
    return new T(); 
}

但目前尚不清楚,为什么会有dr参数。