早聞.NET 2.0中泛型的大名,但一直未在實際開發中使用。
最近在開發部落格園網站程式的過程中體驗了一下。
應用場景:
在設定檔中透過反序列化讀取對應的郵件設定。
設定檔範例:
<BlogConfigurationSettings>
<MailSettings>
<MailSetting Name="ApproveEmail" SmtpServer="smtp.126.com" EmailFrom="" UserName="" PassWord=""></MailSetting>
<MailSetting Name="ContactEmail" SmtpServer="smtp.163.com" EmailFrom="" UserName="" PassWord=""></MailSetting>
</MailSettings>
</BlogConfigurationSettings>
功能說明:
透過此設定文件,反序列化得到BlogConfigurationSettings實例的屬性MailSettings,然後根據關鍵字得到對應的MailSetting,例如:名為ApproveEmail的MailSetting。
MailSetting的定義:
MailSetting
[Serializable]
public class MailSetting
{
private string _name;
[XmlAttribute("Name")]
public string Name
{
get { return _name; }
設置 { _name = 值; }
}
private string _smtpServer;
[XmlAttribute("SmtpServer")]
public string SmtpServer
{
get { return _smtpServer; }
設置 { _smtpServer = value; }
}
private string _mailFrom;
[XmlAttribute("MailFrom")]
public string MailFrom
{
get { return _mailFrom; }
設定 { _mailFrom = value; }
}
private string _username;
[XmlAttribute("UserName")]
public string UserName
{
get { return _username; }
設置 { _username = 值; }
}
private string _password;
[XmlAttribute("Password")]
public string Password
{
get { return _password; }
set { _password = value; }
}
public string Key
{
get { return this.Name; }
}
}
如果不使用泛型,我們可以透過陣列或集合類別來實現。
對於數組,我們需要在BlogConfigurationSettings進行這樣的定義:
private MailSetting [] __mailSettings;
[XmlArray("MailSettings")]
public MailSetting [] MailSettings
{
get { return this._mailSettings; }
set { this._mailSettings = value; }
}我們還需要寫一個方法去列舉數組元素,根據關鍵字回傳對應的MailSetting。
對於集合類,需要在BlogConfigurationSettings進行這樣的定義:
private MailSettingColletion _mailSettings;
[XmlArray("MailSettings")]
public MailSettingColletion MailSettings
{
get { return this._mailSettings; }
set { this._mailSettings = value; }
}我們需要寫一個MailSettingColletion類別, 並且在MailSettingColletion中實作一個方法去根據關鍵字尋找對應的MailSetting。
對於泛型,我們只要在BlogConfigurationSettings進行如下的定義:
private List<MailSetting> _mailSettings;
[XmlArray("MailSettings")]
public List<MailSetting> MailSettings
{
get { return _mailSettings; }
set { _mailSettings = value;}
}
然後只要下面的一行程式碼就能依照關鍵字得到對應的MailSetting:
BlogConfigurationSettings.MailSettings.Find(delegate(MailSetting mailSetting) { return mailSetting.Key == "ApproveEmail"; })
Find方法的參數型別是Predicate<T>,它的定義是:
public delegate bool Predicate<T>(T obj)
也就是一個參數為泛型,傳回值為bool的委託類型。
Find的功能就是枚舉List<T>中的元素,並以每個元素作為委託的參數呼叫委託,實際的委託方法是透過Find參數傳遞過來的,當呼叫的委託傳回true時,傳回目前元素。
你也可以將上面的Find參數中的程式碼寫為一個單獨的方法,然後將方法名稱作為Find的參數。
BlogConfigurationSettings.MailSettings.Find(IsMe);
public bool IsMe(MailSetting mailSetting)
{
return mailSetting.Key == "ApproveEmail";
}
對於這樣的程式碼,你立即會感到不舒服,這樣豈不要為每個關鍵字寫一個方法,你想應該這樣寫:
public bool IsMe(MailSetting mailSetting,string key)
{
return mailSetting.Key == key;
}
這樣寫當然好啊,可是Find卻不同意,它的參數只允許是帶有一個參數的方法。
那要如何解決這個問題呢?
我想到的一個解決方法,寫一個MailSettingPredicate類別:
public class MailSettingPredicate
{
private string key;
public string Key
{
get { return key; }
設定 { key = 值; }
}
public bool IsMe(MailSetting mailSetting)
{
return mailSetting.Key == this.key;
}
}
在呼叫IsMe之前,先設定MailSettingManager.Key的值,程式碼如下:
MailSettingPredicate predicate= new MailSettingPredicate();
predicate.Key = "ApproveEmail";
Config.Settings.MailSettings.Find(predicate.IsMe);
predicate.Key = "ContactEmail";
Config.Settings.MailSettings.Find(predicate.IsMe);
我在實際開發中剛剛使用.NET 2.0的泛型,寫這篇文章是想加深自己的理解,同時希望給不熟悉.NET 2.0泛型的朋友提供一點參考,不足之處,歡迎您指出。