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?

Foi útil?

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ô.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top