Domanda

Ho un Email oggetto e sto tentando di convalidare il numero di allegati che sono nella sua proprietà List<Attachment>.

Il trucco è che consumiamo il metodo Send() attraverso un servizio WCF. È facile convalidarlo lato server, ma prima voglio convalidarlo lato client.

Ho generato una libreria che altri dovrebbero usare per consumare il servizio, che a sua volta ha un proxy contenente tutti gli oggetti e i metodi disponibili. Penso che dovrei essere in grado di sovraccaricare il metodo Add() su GenericList con del codice personalizzato in modo che la raccolta venga verificata quando viene aggiunto qualcosa e se supera il massimo specificato, viene generata un'eccezione.

public partial class List<Attachment>
{
    public void Add(Attachment item)
    {
        base.Add(item);
        if (this.Count() > maxAttachments)
        {
            throw new Exception("fail")
        }
    }
}

Questo non funziona - Non posso class base.Add () e non posso definire la classe parziale con un tipo specificato.

Come posso creare un sovraccarico per il metodo Add in modo da poter includere del codice personalizzato?

È stato utile?

Soluzione

Se possiedi la classe Email, l'opzione migliore sarebbe quella di cambiare il tipo sottostante del membro Elenco in un'implementazione specializzata di un elenco.

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);
    }

    // ...
    // ...
}

È un po 'un sacco di codice boilerplate, ma è davvero l'unico modo per sovrascrivere chiaramente il comportamento.

Tuttavia, se non possiedi la classe <=>, non puoi davvero farlo con mezzi tradizionali; avresti bisogno di un hack di riflessione per sostituire il membro sottostante o qualcosa di simile al Managed Extensibility Framework .

Altri suggerimenti

List<T> non è una classe parziale, quindi non puoi estenderla usando le tue classi parziali.

Inoltre, LINQ to Objects non fornisce Add() su IList<T>, fa parte dell'interfaccia System.Collections.ObjectModel.Collection<T> implementata da InsertItem() e RemoveItem() non è un metodo virtuale o astratto in <=>, quindi non puoi ignorarlo.

Quello che dovresti guardare è <=> - questo componente fornisce un'implementazione dell'elenco simile a <=> con la capacità aggiuntiva di sovrascrivere metodi protetti che ti danno un posto per fare attività di validazione.

Non è necessario implementare l'elenco da zero, basta ereditare da esso e sovrascrivere metodi come <=> e <=> per implementare regole personalizzate:


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)
    }
}

<=> chiama <=> sotto il cofano.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top