早聞.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; }
set { _name = value; }
}
private string _smtpserver;
[xmlattribute("smtpserver")]
public string smtpserver
{
get { return _smtpserver; }
set { _smtpserver = value; }
}
private string _mailfrom;
[xmlattribute("mailfrom")]
public string mailfrom
{
get { return _mailfrom; }
set { _mailfrom = value; }
}
private string _username;
[xmlattribute("username")]
public string username
{
get { return _username; }
set { _username = value; }
}
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; }
set { key = value; }
}
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泛型的朋友提供一點參考,不足之處,歡迎您指出。