Sovraccarico del metodo Aggiungi di LINQ per la convalida
-
22-07-2019 - |
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?
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.