2010-10-03 40 views
5

我有這樣的:爲什麼要使用初始值設定項? (.NET)

AudioPlayer player = new AudioPlayer(); 
player.Directory = vc.Directory; 
player.StartTime = vc.StarTime; 
player.EndTime = vc.EndTime; 

我能有這樣的:

AudioPlayer player = new AudioPlayer 
{ 
    Directory = vc.Directory, 
    StartTime = vc.StarTime, 
    EndTime = vc.EndTime 
}; 

如果我轉換成「的東西寫新的方式」,我該怎麼獲得,除了不可讀性?它會讓我更接近lambda函數(=>)嗎?

這是否與RAII有關?

此外:

有的回答說,正常的初始化可以留在「無效」狀態後的對象,例如僅設置一個目錄屬性 - 在這裏我的觀察是,是誰的人正在設計的對象可能是設計的,它在只有真正輸入的值才能通過真正的構造函數輸入,而其他所有元素都可以在以後自由修改。

+0

嗯,好像我對lambda的預感是正確的! – 2010-10-03 13:19:27

+0

查看您最喜愛的C#語言書籍中的「匿名類型」。 – 2010-10-03 14:22:12

+0

@Hans:和'ad-hoc-property-containers'一樣嗎? – 2010-10-03 14:33:21

回答

2

考慮你想將新創建的對象傳遞給某個方法(而不是用其他方法)。你可以寫舊的方式:

AudioPlayer player = new AudioPlayer(); 
player.Directory = vc.Directory; 
player.StartTime = vc.StarTime; 
player.EndTime = vc.EndTime; 
some.Method(player); 

或者你可以使用對象初始化:

some.Method(
    new AudioPlayer 
    { 
     Directory = vc.Directory, 
     StartTime = vc.StarTime, 
     EndTime = vc.EndTime 
    }); 

使用對象initilizers,你可以清楚地看到這段代碼的功能和對象不晚使用。

此外,我認爲可讀性(和「可寫性」)更好:您不必無止境地重複變量名稱。

+0

好吧,這裏是來自VB6的'with'關鍵字! :) – 2010-10-03 13:21:28

1

我相信這個語法已被添加,因爲它更容易與lambda表達式一起使用,所以您可以輕鬆地做一些類似item => new Person() { Name = item.Name }的事情。

我不認爲這有什麼關係RAII雖然..

10

有了這樣一個簡單的例子,你確實沒有多少收穫。然而,它有所不同,當你有這個:

var player = new AudioPlayer 
{ 
    Car = new Car() 
    { 
     WheelSize = new Inch(21), 
     Driver = new Person() 
     { 
      Age = 53, 
      Type = LicenseType.B, 
      Family = 
      { 
       new Person("Jane"), 
       new Person("Pieter"), 
       new Person("Anny") 
      } 
     } 
    } 
    Directory = vc.Directory, 
    StartTime = vc.StarTime, 
    EndTime = vc.EndTime 
}; 

試着用舊的方式做這件事。它變得非常醜陋。

+0

+1。一個簡單的點,但調用無參數構造函數時不需要派生類。 – Ani 2010-10-03 14:32:57

+0

@Ani:這就是爲什麼'新的AudioPlayer'沒有禁忌:-) – Steven 2010-10-03 14:46:02

1

您可以減少21個字符的代碼。代碼越少意味着錯誤越少。爲了獲得更多,您可以使用隱式變量類型推斷:var player = new AudioPlayer {

2

您不僅獲得不可讀性,還可以通過將對象置於無效狀態而獲得更大的能力來引發錯誤。

它唯一與RAII有關的是RAII依賴於明智的不變量,並且初始化器可以很容易地破壞不變量。

但是,它在創建匿名值或創建普通舊數據樣式對象(其中類是一個「啞」的值容器和不變量不重要)中非常有用。這些對於lambda函數和linq表達式可能特別有用,儘管它們對於它們來說既不是絕對必要的,也不限於它們。

當一個類保持一個不變量時,那麼以這種方式初始化它並不是一個好主意,並且作爲一個規則,從一個構造函數重新寫入新語法的值是一個壞主意。

在你的例子中,你的第一個例子並沒有使用它的構造函數來初始化到一個有保證的有效狀態。這是一種難聞的氣味(在播放目錄,開始時間和結束時間之前,播放器的目標是什麼?),但是對於給定的類而言,這是合理的,那麼使用新的語法也是如此。

新語法可以在單個表達式中設置對象,而該表達式又可以成爲另一個表達式的一部分,這可能是有用的,並且確實包含在lambda表達式中。

2

在處理匿名類型時,初始化器變得必需,而不僅僅是有用。

例如爲:

變種X =新的{富= 「foo」 的,酒吧= 「酒吧」};

+0

這個特殊的實例,是否與.net 2.0兼容?即它是IDE,編譯器還是.net運行時的功能? – 2010-10-10 16:51:33

相關問題