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

本文关键字:类型 转换 映射 方法 泛型 | 更新日期: 2023-09-27 18:27:35

我正在尝试创建一个通用映射函数,该函数将接受从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列名暴露给我的业务逻辑。

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

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

where T : new()

然后你就可以

var instance = new T();

此外,编译器只知道T是NSReportBase类型,但当使用T时变成NSPipelineSystemsNSPipelineSegmentGroups,并且不能将NSPipelineSystems分配给NSPipelineSegmentGroups,反之亦然,这就是为什么会出现该错误。

如果你想解决这个问题,你必须改变

T newNamingStandardReport = null;

NSReportBase newNamingStandardReport = null;

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

假定编译器已知T的类型为"NSReportBase"

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

解决方案:先浇筑成object型,然后浇筑成混凝土型。这种方法对我来说仍然是一种破解。也许你应该首先评估是否应该使用泛型。泛型的目的是您的泛型方法不需要关心具体类型

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

但不清楚为什么会有dr参数。