早闻.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泛型的朋友提供一点参考,不足之处,欢迎您指出。