Ouvi falar do nome genérico no .NET 2.0, mas ele não foi usado no desenvolvimento real.
Recentemente experimentei isso durante o desenvolvimento do programa do site Blog Park.
Cenários de aplicação:
Leia as configurações de e-mail correspondentes no arquivo de configuração por meio da desserialização.
Exemplo de arquivo de configuração:
<Configurações de configuração do blog>
<Configurações de correio>
<MailSetting Name="ApproveEmail" SmtpServer="smtp.126.com" EmailFrom="" UserName="" PassWord=""></MailSetting>
<MailSetting Name="ContactEmail" SmtpServer="smtp.163.com" EmailFrom="" UserName="" PassWord=""></MailSetting>
</MailSettings>
</BlogConfigurationSettings>
Descrição da função:
Através do arquivo de configuração, o atributo MailSettings da instância BlogConfigurationSettings é obtido por meio da desserialização, e a seguir o MailSetting correspondente é obtido de acordo com a palavra-chave, por exemplo: o MailSetting denominado ApproveEmail.
Definição de MailSetting:
Configuração de correio
[Serializável]
classe pública MailSetting
{
string privada _nome;
[XmlAttribute("Nome")]
nome da string pública
{
obter {retornar _nome};
definir {_nome = valor};
}
string privada _smtpServer;
[XmlAttribute("ServidorSmtp")]
string pública SmtpServer
{
obter {retornar _smtpServer};
definir {_smtpServer = valor};
}
string privada _mailFrom;
[XmlAttribute("MailFrom")]
string pública MailFrom
{
obter { return _mailFrom }
definir {_mailFrom = valor};
}
string privada _nomedeusuário;
[XmlAttribute("NomeUsuário")]
string pública nome de usuário
{
obter {retornar _nomedeusuário};
definir {_nomedeusuário = valor};
}
string privada _senha;
[XmlAttribute("Senha")]
Senha de string pública
{
obter {retornar _senha};
definir {_senha = valor};
}
chave de string pública
{
obter {retornar este.Nome};
}
}
Se não usarmos genéricos, podemos implementá-los por meio de arrays ou classes de coleção.
Para arrays, precisamos definir isso em BlogConfigurationSettings:
mailSetting privado [] __mailSettings;
[XmlArray("Configurações de Correio")]
MailSetting público [] MailSettings
{
obter {retornar isto._mailSettings};
definir { this._mailSettings = valor };
} Também precisamos escrever um método para enumerar os elementos do array e retornar o MailSetting correspondente com base na palavra-chave.
Para classes de coleção, você precisa definir isso em BlogConfigurationSettings:
private MailSettingCollection _mailSettings;
[XmlArray("Configurações de Correio")]
MailSettingColletion MailSettings público
{
obter {retornar isto._mailSettings};
definir { this._mailSettings = valor };
}Precisamos escrever uma classe MailSettingCollection e implementar um método em MailSettingCollection para encontrar o MailSetting correspondente com base em palavras-chave.
Para genéricos, precisamos apenas definir o seguinte em BlogConfigurationSettings:
lista privada<MailSetting> _mailSettings;
[XmlArray("Configurações de Correio")]
lista pública<MailSetting> MailSettings
{
obter {retornar _mailSettings};
definir { _mailSettings = valor;}
}
Então, apenas a seguinte linha de código pode obter o MailSetting correspondente com base na palavra-chave:
BlogConfigurationSettings.MailSettings.Find(delegate(MailSetting mailSetting) { return mailSetting.Key == "ApproveEmail"; })
O tipo de parâmetro do método Find é Predicate<T> e sua definição é:
delegado público bool Predicate<T>(T obj)
Ou seja, um tipo delegado cujos parâmetros são genéricos e cujo valor de retorno é bool.
A função de Find é enumerar os elementos em List<T> e chamar o delegado com cada elemento como um parâmetro do delegado. O método delegado real é passado através do parâmetro Find. Quando o delegado chamado retorna verdadeiro, o elemento atual é. voltou.
Você também pode escrever o código no parâmetro Find acima como um método separado e, em seguida, usar o nome do método como parâmetro de Find.
BlogConfigurationSettings.MailSettings.Find(IsMe);
public bool IsMe(MailSetting mailSetting)
{
return mailSetting.Key == "ApproveEmail";
}
Você imediatamente se sentirá desconfortável com esse código. Por que não escrever um método para cada palavra-chave?
public bool IsMe(MailSetting mailSetting, chave de string)
{
retornar mailSetting.Key == chave;
}
Claro que é bom escrever desta forma, mas Find discorda. Seus parâmetros só podem ser métodos com um parâmetro.
Então, como resolver esse problema?
Uma solução que pensei foi escrever uma classe MailSettingPredicate:
classe pública MailSettingPredicate
{
chave de string privada;
chave de string pública
{
obter {chave de retorno};
definir {chave = valor};
}
public bool IsMe(MailSetting mailSetting)
{
retornar mailSetting.Key == this.key;
}
}
Antes de chamar IsMe, primeiro defina o valor de MailSettingManager.Key. O código é o seguinte:
MailSettingPredicate predicado= new MailSettingPredicate();
predicado.Key = "ApproveEmail";
Config.Settings.MailSettings.Find(predicado.IsMe);
predicado.Key = "ContactEmail";
Config.Settings.MailSettings.Find(predicado.IsMe);
Acabei de usar genéricos do .NET 2.0 no desenvolvimento real. Escrevo este artigo para aprofundar meu entendimento. Também espero fornecer algumas referências para amigos que não estão familiarizados com os genéricos do .NET 2.0.