在做法 12 提到多個建構函式很容易造成每個建構函式有細微的區別,因此使用 Member Initializers 在宣告時直接賦值以解決這個問題。

這個做法提到了另一種實做多個建構函式的方法,下面這個例子中就是比較不好的做法,因為每個建構函式都有相似的邏輯,並且有新增成員的話 就需要每個建構函式一一補上初始化邏輯。

public class MyClass
{
	public List<int> coll { get; set; }
	public string name { get; set; }
	public MyClass()
	{
		coll = new List<int>();
		this.name = default;
	}
	public MyClass(int initialCount)
	{
		coll = (initialCount > 0) ? new List<int>(initialCount) : new List<int>();
		this.name = default;
	}
	public MyClass(int initialCount, string name)
	{
		coll = (initialCount > 0) ? new List<int>(initialCount) : new List<int>();
		this.name = name;
	}
}

下面第二種做法是把共用的初始化邏輯搬到私有方法裡面,但缺點就是成員是 readonly 這種只能在建構函式初始化的成員沒辦法在私有方法初始化。

public class MyClass
{
	private List<int> coll;
	private string name;
	public MyClass()
	{
		CommonConstructor(0, "");
	}
	public MyClass(int initialCount)
	{
		CommonConstructor(initialCount, "");
	}
	public MyClass(int initialCount, string name)
	{
		CommonConstructor(initialCount, name);
	}
	private void CommonConstructor(int initialCount, string name)
	{
		coll = (initialCount > 0) ? new List<int>(initialCount) : new List<int>();
		this.name = name;
	}
}

上面提到的兩種方法都不太適合,現在可以使用 Constructor initializers 也就是使用 this接在建構函式後面, 這樣就能共用一個最底層的建構函式,也不會有上個例子提到無法初始化的問題。

public class MyClass
{
	private List<int> coll;
	private string name;
	public MyClass() : this(0, "")
	{
	}
	public MyClass(int initialCount) : this(initialCount, string.Empty)
	{
	}
	public MyClass(int initialCount, string name)
	{
		coll = (initialCount > 0) ? new List<int>(initialCount) : new List<int>();
		this.name = name;
	}
}

也可以使用預設值的語法能夠在少寫一個建構函式

public class MyClass
{
	private List<int> coll;
	private string name;
	public MyClass() : this(0, string.Empty)
	{
	}
	public MyClass(int initialCount = 0, string name = "")
	{
		var coll = (initialCount > 0) ? new List<int>(initialCount) : new List<int>();
		this.name = name;
	}
}

Summary

在這個做法中建議是使用 this 來減少建構函式的數量,也盡量減少初始化程式碼的數量,也可以使用做法 12 提到的 Member Initializers 也能進一步減少數量。