具有通用TypeOf的过滤器模式

时间:2018-11-07 09:06:47

标签: c# generics software-design

我正在实现过滤器(条件)模式,我不确定创建通用的TypeOfCriteria的最佳方法是什么。

为了提供一些背景信息,部分过滤系统是特定的,例如,我在UserCriteria文件夹中有一个EmailAddressContains过滤器。用户类是抽象的,从该基类继承有几种不同的用户类型,例如AdminUser和FullControlUser。系统的其他部分具有相似的继承树。最初,我实现了诸如TypeOfAdminUser之类的特定TypeOf条件,但很快我就知道可以使它更通用。

我想出了三种方法,但不确定哪一种是“最好的”。也许还有另一种我尚未想到的方法。

方法1

public interface ICriteria<T> where T : BaseEntity
{
    IEnumerable<T> MeetCriteria(IEnumerable<T> entities);
}

public class TypeOfCriteria<T> : ICriteria<T> where T : BaseEntity
{
    private readonly Type _type;

    public TypeOfCriteria(Type type)
    {
        _type = type;
    }

    public IEnumerable<T> MeetCriteria(IEnumerable<T> entities)
    {
        return from T entity in entities
               where entity.GetType().Equals(_type)
               select entity;
    }
}

用法:

ICriteria<User> criteria = new TypeOfCriteria<User>(typeof(AdminUser));
admins = criteria.MeetCriteria(users);

方法2

public interface ICriteria<T> where T : BaseEntity
{
    IEnumerable<T> MeetCriteria(IEnumerable<T> entities);
}

public class TypeOfCriteria<T, TResult> : ICriteria<T>
    where T : BaseEntity
    where TResult : BaseEntity
{
    public IEnumerable<T> MeetCriteria(IEnumerable<T> entities)
    {
        return entities.OfType<TResult>().Cast<T>();
    }
}

用法:

ICriteria<User> criteria = new TypeOfCriteria<User, AdminUser>();
admins = criteria.MeetCriteria(users);

方法3

public interface ICriteria<T> where T : BaseEntity
{
    IEnumerable<T> MeetCriteria<TResult>(IEnumerable<T> entities);
}

public class TypeOfCriteria<T> : ICriteria<T> where T : BaseEntity
{
    public IEnumerable<T> MeetCriteria<TResult>(IEnumerable<T> entities)
    {
        return entities.OfType<TResult>().Cast<T>();
    }
}

用法:

ICriteria<User> criteria = new TypeOfCriteria<User>();
admins = criteria.MeetCriteria<AdminUser>(users);

优点和缺点

方法1的感觉与我的其他Criteria类最相似,在该类中,我在构造函数(新的EmailAddressContains(“。com”))中传递了实际的条件。

方法2的MeetCriteria实现感觉更干净。我不确定性能,这看起来可能会更快,但这并不是我为此项目担心的指标。

我至少喜欢方法3,因为它需要我更改界面。

0 个答案:

没有答案