C#将构造函数参数绑定到实例变量

时间:2012-08-28 12:27:22

标签: c# constructor

很常见的场景:我有一个包含多个实例变量的类和一个接受多个参数的构造函数。我能以某种方式将一个绑定到另一个吗?将所有参数分配给实例变量非常冗长,并且是配置约定原则可以(并且应该)涵盖的情况之一。我的示例代码如下所示:

public class myClass
{    
    private object param1;
    private object param2;
    private object param3;
    private object param4;

    public myClass(object param1, object param2, object param3, object param4)
    {
        this.param1 = param1;
        this.param2 = param2;
        this.param3 = param3;
        this.param4 = param4;
    }
}

是否有简单方式摆脱这种情况并让C#自动完成它的魔力?

3 个答案:

答案 0 :(得分:5)

C#语言中没有任何内容可以涵盖这一点,没有。虽然工具可以为您生成代码,但它们可能不一定会保持最新状态,您仍然可以使代码存在且可见。您可以潜在在某些情况下使用反射来执行此操作,例如:

public MyClass(object param1, object param2, object param3, object param4)
{
    Helpers.PopulateFromConstructor(this, param1, param2, param3, param4);
}

...您需要以与参数相同的顺序指定值,并保持名称与字段等相同。您可能还会发现字段为readonly时出现问题

就我个人而言,我只是吮吸它 - 如果你愿意,可以使用工具来生成代码,但除此之外只需要使用它。

请注意,您可能希望在设置字段时进行验证,尤其是在无效范围内。所以你的构造函数体可能实际结束了这样:

public myClass(object param1, object param2, object param3, object param4)
{
    this.param1 = Preconditions.CheckNotNull(param1);
    this.param2 = param2;
    this.param3 = Preconditions.CheckNotNull(param3);
    this.param4 = param4;
}

(当然,对于一个合适的Preconditions类。我在Java代码中无意中从Guava中剔除了这个想法,因为我在日常编码中使用它。这是我们在{ {3}}也是。)

答案 1 :(得分:4)

“......可能(并且应该)被配置约定原则覆盖......”

“约定优于配置”通常适用于API或框架,例如MVC或实体框架,而不适用于语言本身。 API通常是一个集中的,可重用的,并且首先是简化功能的抽象。在这种情况下,规定惯例有助于在不影响功能的情况下驱动结构。

然而,编程语言并非如此。相比之下,语言是广泛的,低级的,复杂的。它应该尽可能少地限制用户,而不会稀释语言的价值。假设这样一个广泛的“惯例”将是非常规范的。除此之外,编译器认为具有给定名称​​的参数必须始终分配给具有相似名称的私有字段是危险的。

首先,您的惯例不是唯一常用的惯例。例如,一种常见的编码样式表示下划线引导的私有字段(_param1),您的约定会错过这些字段。构造函数可能具有超出这些赋值的进一步逻辑,在这种情况下,您的约定太简单了:“约定驱动”代码是应该在任何其他构造函数逻辑之前还是之后执行?

最重要的是,如何覆盖这样的惯例?如果在构造函数中,您以其他方式使用param1,那么您仍然执行约定吗?如果在构造函数中我为this.param1分配了不同的值,该怎么办?您的约定应该在用户添加的代码之前还是之后发生?

即使是这些简短的问题 - 许多人将会有非常不同且同样有效的答案 - 足以表明这样的惯例并不像看起来那么明显,也不容易定义。

答案 2 :(得分:2)

虽然有很多插件可以做这种事情 - 但值得注意的是,如果VS2010 +的本机能力在匹配构造函数不存在时从模型调用生成构造函数,则可以使用简单的键盘快捷键来执行为你工作。

即。如果我是一个存根类:

class MyClass{

}

然后在某个方法我写这样的东西:

object p1, p2, p3;
//...  (get values for p1-3)
var a = new MyClass(p1, p2, p3);

当这样的构造函数不存在时,会出现一个小帮助按钮。如果单击它,或按ALT+SHIFT+F10(默认情况下),您将获得一个菜单,其中一个选项是生成存根构造函数,然后将更改MyClass代码,如下所示: / p>

class MyClass
{
    private object p1;
    private object p2;
    private object p3;

    public MyClass(object p1, object p2, object p3)
    {
        // TODO: Complete member initialization
        this.p1 = p1;
        this.p2 = p2;
        this.p3 = p3;
    }

}