1

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

4

3 回答 3

2

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

where T : new()

那么你就可以

var instance = new T();

此外,错误来自编译器只知道 T 是 TypeNSReportBase但是当使用 T 成为NSPipelineSystemsorNSPipelineSegmentGroups并且您不能分配NSPipelineSystemsNSPipelineSegmentGroups或反之亦然的事实,这就是您收到该错误的原因。

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

T newNamingStandardReport = null;

NSReportBase newNamingStandardReport = null;

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

于 2013-08-14T14:06:24.550 回答
1

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

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

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

于 2013-08-14T18:37:21.057 回答
0
internal static T BuildNamingStandardType<T>(DataRow dr) where T : NSReportBase, new()
{
    return new T(); 
}

但不清楚,为什么有一个dr参数。

于 2013-08-14T14:07:23.533 回答