代码之家  ›  专栏  ›  技术社区  ›  Moe Sisko

构造函数链

  •  4
  • Moe Sisko  · 技术社区  · 16 年前

    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转换成一个包含一个成员的列表。代码通过助手函数“CreateList”工作,但我想知道是否有比这更干净的方法。i、 是否有一些方法可以不用helper方法来完成这项工作。

    4 回复  |  直到 16 年前
        1
  •  6
  •   Rex M    16 年前

    尝试:

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

    IEnumerable<T> (这是一组 T[]

        2
  •  3
  •   Josh Bush    16 年前

    我将放弃ListHelper,转而支持以下内容:

    public CA(string s, int num) : this(s, new List<int>(){num}){}
    
        3
  •  0
  •   Dynami Le Savard    16 年前

    我的扩展中有一点东西,当我没有可枚举的东西来启动一个列表时,应该可以做到这一点。

    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())
        {
        }
    }
    
        4
  •  0
  •   Mark Jones    15 年前

    查看您的代码,我假设您希望使用第一个CA构造函数进行初始化,而第二个CA构造函数(string,int)不需要自己进行初始化——它只将控制权传递给第一个CA构造函数。

    首先,构造函数链接的经验法则是实现链接的主要目的-消除重复或过于复杂的初始化代码(即,链中的最低级别是唯一包含任何实际初始化代码的构造函数)。您的示例已经在这样做了,这很好。

    第二,如果您使用的是.NET4,那么可以在构造函数上使用可选参数来消除不必要的额外构造函数,从而消除链接的需要。因此,您可以通过以下方式实现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值,而不影响客户端。

    如果您确实需要一个泛型的、可扩展的类型,那么使用动态类型可以为客户机和类提供更清晰的代码。

    希望这有帮助,

    做记号

    推荐文章