2010-01-20 109 views
4

示例代碼:構造函數鏈

public class CA 
{ 
    public CA(string s, List<int> numList) 
    { 
     // do some initialization 
    } 

    public CA(string s, int num) : this(s, ListHelper.CreateList(num)) 
    { 
    } 
} 

public static class ListHelper 
{ 
    public static List<int> CreateList(int num) 
    { 
     List<int> numList = new List<int>(); 
     numList.Add(num); 
     return numList; 
    } 
} 

在 「CA」 第二個構造函數使用構造函數鏈。在「this」調用中,我想將int轉換爲帶有一個成員的List。該代碼通過幫助函數「CreateList」工作,但我想知道是否有比這更清潔的方式。即沒有輔助方法,有沒有辦法做到這一點。

到目前爲止,在這樣的情況下,我可能不會打擾使用構造函數鏈。想法?

+0

我真的只是發現它有助於嘗試升級現有的功能,而不會損壞黑匣子時。 – 2010-01-20 03:32:01

回答

6

嘗試:

public CA(string s, int num) : this(s, new List<int>(new int[] { num })) 
{ 
} 

這應該與構造過載它接受一個IEnumerable<T>(其中T[]陣列可轉化成)。

3

我會溝ListHelper贊成如下:

public CA(string s, int num) : this(s, new List<int>(){num}){} 
+0

編譯器似乎不喜歡這樣? (給出語法錯誤 - 至少在VS2005中) – 2010-01-20 03:58:35

+1

是的,這裏使用的構造是C#3.0中的新成員。請參閱http://msdn.microsoft.com/en-us/library/bb308966.aspx#csharp3.0overview_topic14 – ephemient 2010-01-20 04:01:37

+0

@ephemient - 謝謝你清除 – 2010-01-20 04:03:13

0

我在擴展一個小東西時,我沒有東西可枚舉的啓動列表,應該做的招。

namespace Linq1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      int value = 10; 
      List<int> list = value.ToList(); 
     } 
    } 

    public static class Extensions 
    { 
     public static List<T> ToList<T>(this T lonely) where T : struct 
     { 
      return new List<T>(new T[] { lonely }); 
     } 
    } 
} 

,並在你的代碼中使用:

public class CA 
{ 
    public CA(string s, List<int> numList) 
    { 
     // do some initialization 
    } 

    public CA(string s, int num) : this(s, num.ToList()) 
    { 
    } 
} 
+0

擴展方法在C#3.0中也是新的:http://msdn.microsoft .COM/EN-US /庫/ bb308966.aspx#csharp3.0overview_topic3 – ephemient 2010-01-20 15:02:32

0

在你的代碼看,我假定你想使用的第一個CA的構造函數做初始化,第二CA構造函數(String, int)不需要自己初始化 - 它只是將控制權交給第一個控制權。

首先,構造函數鏈的經驗法則是完成鏈接的主要目的 - 消除重複或過於複雜的初始化代碼(即鏈中的最低級別是唯一包含任何實際初始化代碼的構造函數) 。你的例子已經在做這個,這很好。其次,如果您使用的是.NET 4,則可以在構造函數中使用可選參數來除去不必要的附加構造函數,從而消除鏈接的需要。所以你可以這樣實現CA:

public class CA 
    { 
     public CA(string s, List<int> numList = null, int num = 0) 
     { 
      // do some initialization 
      if (numList == null) 
      { 
       numList = new List<int>(); 
       numList.Add(num); 
      } 
     } 
    } 

現在你只有一個構造函數,所以鏈接是不必要的。你的幫助函數和靜態類也是不必要的。使用上述定義客戶端代碼會是這樣的:

 int iMyInt = 1; 
     List<int> myIntList = new List<int>(); 
     myIntList.Add(iMyInt); 
     CA caListMethod = new CA("ListMethod", myIntList); 
     CA caIntMethod = new CA("IntMethod", null, iMyInt); 

如果你不喜歡「caIntMethod」撥打以上出於某種原因,你可以使用.NET 4,動態類型,可以另一項新功能使客戶端代碼更清潔。您的CA類可以是這個樣子,而不是:

public class CA 
    { 
     public CA(string s, dynamic InitValue) 
     { 
      List<int> InitList = null; 
      if (InitValue is List<int>) 
       InitList = InitValue; 
      else if (InitValue is int) 
      { 
       InitList = new List<int>(); 
       InitList.Add(InitValue); 
      } 

      // Now, InitList contains your list for further initialization, 
      // if the client passed either a List<int> or an int: 
      if (InitList != null) 
      { 
       // do some initialization 
      } 
     } 
    } 

而新的客戶端代碼會是這個樣子:

 int iMyInt = 1; 
     List<int> myIntList = new List<int>(); 
     myIntList.Add(iMyInt); 
     CA caListMethod = new CA("ListMethod", myIntList); 
     CA caIntMethod = new CA("IntMethod", iMyInt); 

你會發現在這個客戶端代碼從前面的例子中,唯一的區別是現在你只有一個構造函數接受兩個參數,而第二個參數具有動態類型。因此,您可以在將來增強您的構造函數以處理許多其他類型的init值,而不會影響客戶端。

對我的第二個例子的警告是動態類型在運行時自動執行類型強制,這是一點處理開銷。但是,如果您想使用某種「通用」構造函數來允許泛型引用的多態性(因此,我提到了可擴展性),那麼無論如何,您都會在自己的代碼中進行類型檢查和強制。動態的美妙之處在於,.NET 4運行時代替你在自己的代碼中處理這些東西,而不是爲你做。所以就性能而言,它通常是一種洗滌。

如果您確實需要一個通用的可擴展類型,那麼使用動態類型可以爲客戶端和類提供更簡潔的代碼。

希望這有助於

馬克