類別 Client 有三個屬性:clientCode、clientName、abbreviation。開發者希望在同一個類別中,根據不同 ComboBox 的綁定需求,分別顯示不同的字串組合(如「代碼-名稱」、「僅名稱」等),但 ToString() 只能有一個實作,無法直接滿足多樣化顯示。
public override string ToString() {
return clientCode, clientName, contacts; // CS1002: ; expected / 錯誤語法
}
public class Client {
public string ClientCode { get; set; }
public string ClientName { get; set; }
public string Abbreviation { get; set; }
// 預設顯示策略:代碼,名稱,縮寫
public Func<Client, string> DisplaySelector = c =>
$"{c.ClientCode},{c.ClientName},{c.Abbreviation}";
public override string ToString() => DisplaySelector(this);
}
var client = new Client {
ClientCode = "C001",
ClientName = "張三",
Abbreviation = "ZS"
};
// ComboBox1:顯示完整資訊(預設)
comboBox1.Items.Add(client); // 輸出:C001,張三,ZS
// ComboBox2:僅顯示名稱
client.DisplaySelector = c => c.ClientName;
comboBox2.Items.Add(client); // 輸出:張三
// ComboBox3:自訂格式「代碼-縮寫」
client.DisplaySelector = c => $"{c.ClientCode}-{c.Abbreviation}";
comboBox3.Items.Add(client); // 輸出:C001-ZS
DisplaySelector 即時生效,支援動態 UI 需求。ToString() 仍保留標準行為,不影響序列化、日誌等其他場景。| 方案 | 優點 | 缺點 |
|---|---|---|
| 重寫 ToString 固定格式 | 簡單 | 無法適配多種顯示需求 |
| 建立多個 ViewModel/DTO | 關注點分離 | 類別爆炸,維護成本高 |
| 實作 IFormattable | 標準化格式化 | ComboBox 不自動調用 ToString(format, provider) |
| 委託策略模式(推薦) | 靈活、零侵入、運行時可變 | 需注意委託為 null 時的預設處理 |
最佳實踐: 在建構子中初始化
DisplaySelector為預設值,避免 NullReferenceException;若專案使用 MVVM,建議將顯示邏輯移至 ViewModel 的DisplayText屬性,讓 View 純粹綁定。