2012-08-28 93 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