Question

J'ai un objet Email et je tente de valider le nombre de pièces jointes contenues dans sa propriété List<Attachment>.

L'astuce consiste à utiliser la méthode Send() sur un service WCF. Il est facile de valider le côté serveur, mais je veux d'abord le valider côté client.

J'ai généré une bibliothèque que d'autres sont supposés utiliser pour consommer le service, qui à son tour dispose d'un proxy contenant tous les objets et les méthodes disponibles. Je pense que je devrais pouvoir surcharger la méthode Add() de la liste générique avec un code personnalisé afin que la collection soit vérifiée lorsque tout élément est ajouté. S'il dépasse le maximum spécifié, une exception est levée.

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

Cela ne fonctionne pas - je ne peux pas classer base.Add () ni définir de classe partielle avec un type spécifié.

Comment créer une surcharge pour la méthode Add afin d'inclure du code personnalisé?

Était-ce utile?

La solution

Si vous possédez la classe Email, la meilleure option serait de modifier le type sous-jacent du membre de liste en une implémentation spécialisée d'une liste.

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

    // ...
    // ...
}

C’est un peu beaucoup de code passe-partout, mais c’est vraiment le seul moyen de modifier le comportement de façon propre.

Toutefois, si vous n'aimez pas la classe <=>, vous ne pouvez pas le faire par des moyens traditionnels; vous auriez besoin d'un hack de réflexion pour remplacer le membre sous-jacent ou quelque chose comme le structure d'extensibilité gérée .

Autres conseils

List<T> n'est pas une classe partielle, vous ne pouvez donc pas l'étendre en utilisant vos propres classes partielles.

En outre, LINQ to Objects ne fournit pas Add() sur IList<T>, cela fait partie de l'interface System.Collections.ObjectModel.Collection<T> implémentée par InsertItem(), et RemoveItem() n'est pas une méthode virtuelle ou abstraite dans <=>. vous ne pouvez pas le remplacer.

Ce que vous devriez regarder, c’est <=> - ce composant fournit une implémentation de liste similaire à <=> avec la possibilité supplémentaire de remplacer les méthodes protégées qui vous offrent un emplacement pour effectuer des tâches de validation.

Vous n'avez pas à implémenter la liste à partir de rien, vous en avez simplement hérité et redéfini des méthodes telles que <=> et <=> pour implémenter des règles personnalisées:


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

<=> appelle <=> sous le capot.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top