Sobrecarga Add método de LINQ para validação
-
22-07-2019 - |
Pergunta
Eu tenho um objeto Email
e estou tentando validar o número de anexos que estão em sua propriedade List<Attachment>
.
O truque é que nós consumimos o método Send()
através de um serviço WCF. É fácil para validá-lo do lado do servidor, mas eu quero validá-lo do lado do cliente em primeiro lugar.
I geraram uma biblioteca que outros são suposto uso, a fim de consumir o serviço, que por sua vez tem um proxy que contém todos os objetos e métodos disponíveis. Eu acho que deve ser capaz de sobrecarregar o método Add()
na GenericList com algum código personalizado para que a coleção é verificada quando nada é adicionado, e se exceder o máximo especificado, em seguida, uma exceção é lançada.
public partial class List<Attachment>
{
public void Add(Attachment item)
{
base.Add(item);
if (this.Count() > maxAttachments)
{
throw new Exception("fail")
}
}
}
Isso não funciona -. Eu não posso classe base.Add () e eu não posso definir classe parcial com um tipo especificado
Como faço para criar uma sobrecarga para o método Add para que eu possa incluir algum código personalizado?
Solução
Se você possui a classe Email
, sua melhor opção seria mudar o tipo subjacente do membro de lista para uma implementação especializada de uma lista.
public class Email
{
const int MaxAttachments = /* ... */;
public Email(/* ... */)
{
this.Attachments = new FixedSizeList<Attachment>(MaxAttachments);
}
// ...
public IList<Attachment> Attachments
{
get;
private set;
}
}
class FixedSizeList<T> : IList<T>
{
List<T> innerList;
int maxCount;
public FixedSizeList(int maxCount)
{
this.innerList = new List<T>(maxCount);
this.maxCount = maxCount;
}
// override all the IList<T> members here by delegating
// to your innerList ...
// ...
public void Add(T item)
{
if (this.Count == this.maxSize)
{
throw new InvalidOperationException("No more items can be added.");
}
this.innerList.Add(item);
}
// ...
// ...
}
É uma espécie de um monte de código clichê, mas isso é realmente a única maneira de limpa substituir o comportamento.
No entanto, se você não possuir a classe Email
, você realmente não pode fazer isso através de meios tradicionais; você precisa de um hack reflexão para substituir o membro subjacente ou algo como o Managed extensibilidade Framework.
Outras dicas
List<T>
não é uma classe parcial, então você não pode estender-lo usando suas próprias classes parciais.
Além disso, LINQ to Objects não fornece Add()
em List<T>
, isso é parte da interface IList<T>
implementado por List<T>
e Add()
não é um método virtual ou resumo em List<T>
, então você não pode substituí-lo.
O que você deve olhar é System.Collections.ObjectModel.Collection<T>
- este componente fornece uma implementação lista semelhante ao List<T>
com a capacidade adicional para substituir métodos protegidos que lhe dão um lugar para fazer tarefas de validação
Você não tem que implementar a lista a partir do zero, você só herdar a partir dele, e métodos de substituição, tais como InsertItem()
e RemoveItem()
para implementar regras personalizadas:
using System.Collections.ObjectModel;
public class EmailCollection : Collection<Email>
{
public int MaximumAttachments { get; set; }
protected override void InsertItem(int index, Email item)
{
if (Count == MaximumAttachments)
{
... throw error
}
// do actual insert
base.InsertItem(index, item)
}
}
Add()
chama InsertItem()
sob o capô.