链式重载构造函数?

Mik*_*ike 3 c# constructor

我正在尝试构建一个类,它将通过传入对数据库中的记录的引用来启动其自身(意图是对数据库运行查询,并且将在其中设置对象属性的返回值) ),或通过"手动"指定值 - 这不需要数据库调用.

我看了几本教科书,发现了这个功能的"最佳实践",遗憾的是我做得很短.

我写了几个示例控制台应用程序,反映了我认为最可能的两个解决方案,但我不知道哪个是最好的正确实现?

示例应用程序#1使用了大多数书籍告诉我的"首选"方式,但大多数示例与这些声明一起提供并不符合我的情况.我在这里担心流程不如App#2那么可读.

using System;

namespace TestApp
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var one = new OverloadedClassTester();
            var two = new OverloadedClassTester(42);
            var three = new OverloadedClassTester(69, "Mike", 24);

            Console.WriteLine("{0}{1}{2}", one, two, three);

            Console.ReadKey();
        }        
    }

    public class OverloadedClassTester
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public int age { get; set; }

        public OverloadedClassTester() : this(0) { }

        public OverloadedClassTester (int _ID) : this (_ID, "", 0)
        {
            this.age = 14;  // Pretend that this was sourced from a database
            this.Name = "Steve"; // Pretend that this was sourced from a database
        }

        public OverloadedClassTester(int _ID, string _Name, int _age)
        {
            this.ID = _ID;
            this.Name = _Name;
            this.age = _age;
        }

        public override string ToString()
        {
            return String.Format("ID: {0}\nName: {1}\nAge: {2}\n\n", this.ID, this.Name, this.age);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

此示例(应用程序#2)"看起来"更具可读性 - 因为我认为更容易看到操作流程.然而,就保存的字符而言,它看起来确实有效:p.此外,它在完全初始化之前调用对象的方法是不危险的,还是这不是一个问题?

using System;

namespace TestApp
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var one = new OverloadedClassTester();
            var two = new OverloadedClassTester(42);
            var three = new OverloadedClassTester(69, "Mike", 24);

            Console.WriteLine("{0}{1}{2}", one, two, three);

            Console.ReadKey();
        }        
    }

    public class OverloadedClassTester
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public int age { get; set; }

        public OverloadedClassTester()
        {
            initialise(0, "", 21); // use defaults.
        }

        public OverloadedClassTester (int _ID)
        {
            var age = 14;  // Pretend that this was sourced from a database (from _ID)
            var Name = "Steve"; // Pretend that this was sourced from a database (from _ID)

            initialise(_ID, Name, age);
        }

        public OverloadedClassTester(int _ID, string _Name, int _age)
        {
            initialise(_ID, _Name, _age);
        }

        public void initialise(int _ID, string _Name, int _age)
        {
            this.ID = _ID;
            this.Name = _Name;
            this.age = _age;
        }

        public override string ToString()
        {
            return String.Format("ID: {0}\nName: {1}\nAge: {2}\n\n", this.ID, this.Name, this.age);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

解决这个问题的"正确"方法是什么?为什么?

谢谢,

Jon*_*eet 12

我肯定会链接构造函数,因此只有其中一个执行"实际工作".这意味着你只需要做到真正的工作在一个地方,所以如果工作变动(例如,你需要调用一些验证方法,在构造函数的结尾)你只有一个地方,你需要改变的代码.

使用更多参数调用"简单"重载是一种非常常见的模式IME.我发现它比第二个版本更具可读性,因为您可以轻松地告诉调用一个重载将与使用默认值调用"更大"的重载相同.对于第二个版本,您必须比较构造函数的主体.

我尽量不要有一个以上的构造函数链直接向基类尽可能 - 除非它链接到一个不同的基类构造函数,当然(如与典型的例外).