具有新类型约束的通用构造函数

3

我有两种类型的对象,数据库模型和普通系统模型。

我希望能够将模型转换为数据库模型,反之亦然。

以下是我编写的方法:

 public static E FromModel<T, E>(T other) 
            where T : sysModel
            where E : dbModel
{
     return new E(other);
}

基本上,sysModeldbModel都是抽象的。 dbModel有很多继承类,它们都有复制构造函数。
我收到了以下错误信息:

Cannot create an instance of type parameter 'E' becauase it does not have the new() constraint

我知道,从技术上讲,有时候可能并没有为每个值的T提供匹配的构造函数,至少这是调试器所知道的。
我还尝试添加了where E : dbModel, new()的限制条件,但这只是无关紧要的。
是否有一种通用方法将一个模型转换为另一个模型,并使用参数?
谢谢。

1
new() 约束用于指定该类型具有没有参数的构造函数。您可能需要通过公开所需复制构造的接口引入某种通用工厂方法。 - Anthony
我知道,我真的想避免将构造函数作为参数传递。 - Ori Refael
1
你不能在泛型类型参数上强制存在带参数的构造函数。你只能使用Activator.CreateInstance来实现,并祈求所使用的类型具有匹配的构造函数。通常,使用泛型类型的解决方案应该避免这种情况,因为你正在对实现施加硬依赖。这有点像说“我希望这个方法能够构造任何类型的存储类,任何类型,但它必须在构造函数中有一个字符串参数,并且必须是文件名”。 - Lasse V. Karlsen
1
相反,你应该引入一个工厂对象的存在,它有一个方法来接受正确类型的参数并构造你需要使用的对象。这样,你至少将那个强依赖关系从实际类型中移开了一层。 - Lasse V. Karlsen
或者你可以将方法放置在它所属的类型中,正确的类型,并实现它以接受正确类型的输入。我假设要转换的类型与要转换到的类型之间存在一对一的关系。在这种情况下,只需在每个类型中放置一个具有正确参数和输出类型的静态方法即可。 - Lasse V. Karlsen
显示剩余4条评论
1个回答

6

要在泛型类型上使用new,您需要在类/方法定义中指定new()约束:

public static E FromModel<T, E>(T other) 
        where T : sysModel
        where E : dbModel, new()

既然你在构造函数中使用了参数,那么就不能使用new,但是你可以使用Activator代替,并将other作为参数传递:

public static E FromModel<T, E>(T other)
    where T : sysModel
    where E : dbModel
{
    return (E)Activator.CreateInstance(typeof(E), new[]{other});
}

似乎可以编译。会导致崩溃的是什么?似乎可以抛出各种异常。我理解必须找到一个使用T的匹配构造函数,对吗? - Ori Refael
没错。如果 E 没有一个接受单个参数 T 的构造函数,那么它将抛出异常。 - Manfred Radlwimmer
太棒了,我希望无论如何都能发生这种情况以防止数据库中的错误和漏洞。我会在2分钟内接受。 - Ori Refael

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接