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

C# 泛型映射方法无法转换为具体类型,c#,generics,.net-4.5,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)

我正在尝试创建一个通用映射函数,该函数将接受所有从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 BuildingStandardType(DataRow dr),其中T:NSReportBase,new()
{
T newNamingStandardReport=null;
if(类型(T)为NSPipelineSystems)
newNamingStandardReport=新的管道系统(dr[“Column1”]、dr[“Column2”]);
else if(类型(T)为NspipelineSegmentGroup)
newNamingStandardReport=新的NSPipelineSegmentGroup(dr[“Column3”]);
返回newNamingStandardReport;
}
但是,我得到一个错误,即每个具体类型都不能隐式转换为类型“T”。鉴于编译器已知T的类型为“NSReportBase”,我不确定是否理解这里的问题,更不用说如何修复它了


编辑:我可能过度简化了示例。挑战在于,构造函数实际上并不接受任何参数,而是从作为方法参数的DataRow获取不同数量和类型的列。我知道我可以通过多态方式实现这一点,但我希望通过将此方法移动到相应的域对象中,避免将DataRow列名暴露于我的业务逻辑。

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

where T : new()
那你就可以

var instance = new T();
此外,错误还来自以下事实:编译器只知道T的类型为
NSReportBase
,但当使用T时,T变为
NSPipelineSystems
NSPipelineSegmentGroups
,并且不能将
NSPipelineSystems
分配给
NSPipelineSegmentGroups
,反之亦然,这就是为什么会出现这种错误

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

T newNamingStandardReport = null;

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

内部静态T BuildingNamingStandardType(DataRow dr),其中T:NSReportBase,new()
{
返回新的T();
}
但不清楚为什么会有一个
dr
参数

假设编译器已知T的类型为“NSReportBase”

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


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

您理解我的答案吗?甚至考虑过?
NSReportBase newNamingStandardReport = null;
internal static T BuildNamingStandardType<T>(DataRow dr) where T : NSReportBase, new()
{
    return new T(); 
}