重载LINQ的Add方法进行验证

时间:2009-09-18 05:06:22

标签: c# .net linq overloading

我有一个Email对象,并且我正在尝试验证其List<Attachment>属性中的附件数量。

诀窍是我们在WCF服务中使用Send()方法。验证服务器端很容易,但我想先在客户端进行验证。

我已经生成了一个其他人应该使用的库,以便使用该服务,而该服务又包含一个包含所有对象和可用方法的代理。我想我应该能够使用一些自定义代码重载GenericList上的Add()方法,以便在添加任何内容时检查集合,如果它超过指定的最大值,则抛出异常。

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

这不起作用 - 我无法对base.Add()进行分类,并且我无法定义具有指定类型的分部类。

如何为Add方法创建重载,以便我可以包含一些自定义代码?

2 个答案:

答案 0 :(得分:2)

如果您拥有Email类,那么最好的选择是将List成员的基础类型更改为列表的专用实现。

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

    // ...
    // ...
}

这是很多样板代码,但这确实是干净地覆盖行为的唯一方法。

但是,如果您拥有Email课程,则无法通过传统方式实现这一目标;你需要一个反射黑客来替换潜在的成员或类似Managed Extensibility Framework

答案 1 :(得分:1)

List<T>不是部分类,因此您无法使用自己的部分类扩展它。

此外,LINQ to Objects未在Add()上提供List<T>,这是IList<T>实现的List<T>接口的一部分,Add()不是<{1}}中的虚拟或抽象方法,因此您无法覆盖它。

你应该看看List<T> - 这个组件提供了一个类似于System.Collections.ObjectModel.Collection<T>的列表实现,增加了覆盖受保护方法的能力,这些方法为你提供了验证任务的地方。

您不必从头开始实施列表,只需继承它,并覆盖List<T>InsertItem()等方法来实现自定义规则:

RemoveItem()

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