2012-08-28 94 views
8

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

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

插件一样的CodeRush或JustCode可以自动为您生成该代码。 – sloth

+0

你也可以看看使用代码片段:http://msdn.microsoft.com/en-us/library/ms165392(v=vs.80).aspx然而,像BigYellowCactus提到的那些工具会给你更好的生产力。 –

+2

将Resharper添加到上面的列表中。 –

回答

2

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

I.e.如果我一个存根类:

class MyClass{ 

} 

,然后在某个地方的方法我写的是这样的:

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

当这样的构造函数不存在,会出现一个小帮手按钮。如果你点击那个,或者按ALT+SHIFT+F10(默认),你会得到一个菜单,就这是生成存根构造函数中的一个选项,然后这将改变MyClass代码如下:

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; 
    } 

} 
+2

+1:您也可以使用'ctrl' +'.'来访问相同的菜单(至少在VS2010 Express中)。 –

+0

酷 - 这比三键版本要容易得多! –

+0

这真的很酷。感谢堆。并非我希望的100%,但正如丹指出的那样,我过于关注目前的情况,并没有考虑很多相关方面。所以我猜Ctrl +。它是 :) – Jan

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代码中的想法,因为我用在day-。日常编码,这是我们在Noda Time使用过这种方法。)

+0

+1“吮吸” – hmqcnoesy

4

“......可以(也应该)覆盖的约定优于配置的原则......”

“公约over配置“通常适用于API或框架,如MVC或实体框架,而不适用于语言本身。 API通常是集中的,可重用的,并且简化了功能的抽象。在这种情况下,口述约定可以帮助驱动结构而不影响功能。

但是,这不适用于编程语言。语言比较广泛,层次低,复杂。它应尽可能少地限制用户,而不会影响语言的价值。假设这样一个广泛的“惯例”将是非常规范的。除此之外,编译器假定具有给定名称的参数必须总是被分配给具有类似名称的私有字段将是危险的。

首先,你的约定不是唯一常用的约定。例如,一种常见的编码风格建议下划线领导的私人领域(_param1),这是你的惯例会错过的。构造函数可能会有更多的逻辑,而不仅仅是这些赋值,在这种情况下,您的约定太简单了:应该在任何其他构造函数逻辑之前还是之后执行“约定驱动”代码?

最重要的是,这样一个公约会如何被覆盖?如果在构造函数中,你以其他方式使用param1,那么你仍然执行约定吗?如果在构造函数中,我为this.param1指定了一个不同的值?应该在用户添加的代码之前还是之后进行约定?

即使是这些简单的问题 - 对于这些问题 - 许多人将会得到非常不同而且同样有效的答案 - 足以表明这样的约定并不像看起来那样明显,也不容易定义。

+0

哇,很多好点。我想我要找的是“让我的生活变得轻松”与“让我的生活保持灵活”的斗争的另一章。我想安德拉斯的答案是最好的/最简单但最灵活的方法。 – Jan

+0

而我希望接受2个答案的情况之一! – Jan