Effective C# (Covers C# 6.0), (includes Content Update Program): 50 Specific Ways to Improve Your C#, 3rd Edition By Bill Wagner 讀後心得
本節將介紹擴充方法不當的使用方式,意即不要利用命名空間多載擴充方法;此舉會造成使用端誤用與意圖不明。
範例:
public sealed class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
namespace ConsoleExtension
{
public static class ConoleReport
{
public static string format( this Person target ) =>
$"{target.FirstName,20}, {target.LastName,15}";
}
}
namespace XmlExtension
{
public static class XmlReport
{
public static string format( this Person target ) =>
new XElement( nameof( Person ),
new XElement( nameof( target.LastName ), target.LastName ),
new XElement( nameof( target.FirstName ), target.LastName )
).ToString( );
}
}
用戶端程式:
var somePresidents = new List<Person>
{
new Person
{
FirstName = "George",
LastName = "Washington"
},
new Person
{
FirstName = "Thomas",
LastName = "Jefferson"
},
new Person
{
FirstName = "Abe",
LastName = "Lincoln"
}
};
foreach ( var person in somePresidents )
Debug.WriteLine( p.Format( ) );
這樣設計有幾個問題:
1. ConsoleReport 與 XmlReport 靜態類別皆定義了相同的方法簽章 format,造成用戶端無法透過方法名稱得知意圖。
2. 同時參考兩者 namespace 會造成 compile error。
3. 變更參考 namespace 以達到呼叫不同 format 的方式容易出錯(參考不當)。
4. format 本身不應寫成擴充方法,format 並非由 Person 擴充出去,而是外部使用 Person 物件的方式。
修改後程式碼:
namespace PersonExtensions
{
public static class PersonReports
{
public static string formatAsText( Person target ) =>
$"{target.FirstName,20}, {target.LastName,15}";
public static string formatAsXml( Person target ) =>
new XElement( nameof( Person ),
new XElement( nameof( target.LastName ), target.LastName ),
new XElement( nameof( target.FirstName ), target.LastName )
).ToString( );
}
}
1. 使用明確的方法命名。
2. 並非寫成擴充方法,而是用靜態方法傳入 Person 物件參數。
3. 統一 namespace。
結論:
1. 不要利用命名空間多載擴充方法。
2. 撰寫擴充方法前,先考慮該方法是否應該由該類別"擴充"出去。
1. 不要利用命名空間多載擴充方法。
2. 撰寫擴充方法前,先考慮該方法是否應該由該類別"擴充"出去。