我正在尝试构建一个类,它将通过传入对数据库中的记录的引用来启动其自身(意图是对数据库运行查询,并且将在其中设置对象属性的返回值) ),或通过"手动"指定值 - 这不需要数据库调用.
我看了几本教科书,发现了这个功能的"最佳实践",遗憾的是我做得很短.
我写了几个示例控制台应用程序,反映了我认为最可能的两个解决方案,但我不知道哪个是最好的正确实现?
示例应用程序#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.我发现它比第二个版本更具可读性,因为您可以轻松地告诉调用一个重载将与使用默认值调用"更大"的重载相同.对于第二个版本,您必须比较构造函数的主体.
我尽量不要有一个以上的构造函数链直接向基类尽可能 - 除非它链接到一个不同的基类构造函数,当然(如与典型的例外).