2010-01-20 94 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运行时代替你在自己的代码中处理这些东西,而不是为你做。所以就性能而言,它通常是一种洗涤。

如果您确实需要一个通用的可扩展类型,那么使用动态类型可以为客户端和类提供更简洁的代码。

希望这有助于

马克