泛型基类包装嵌套的泛型类以减少类型参数规范:此模式是否有名称?

本文关键字:模式 有名称 是否 类型参数 嵌套 包装 基类 泛型类 泛型 | 更新日期: 2023-09-27 18:09:55

Ok问题标题远非不言自明。我发现自己经常这样做:

public static class Equality<T>
{
    public static IEqualityComparer<T> CreateComparer<K>(Func<T, K> keySelector)
    {
        return new KeyEqualityComparer<K>(keySelector);
    }

    class KeyEqualityComparer<K> : IEqualityComparer<T>
    {
        readonly Func<T, K> keySelector;
        public KeyEqualityComparer(Func<T, K> keySelector)
        {    
            this.keySelector = keySelector;
        }
        public bool Equals(T x, T y)
        {
            ----
        }
        public int GetHashCode(T obj)
        {
            ....
        }
    }
}

我做了什么:有一个实现细节KeyEqualityComparer<T, K>,我必须调用:

new KeyEqualityComparer<Person, int>(p => p.ID);

通过将其嵌套为私有类,我不仅隐藏了实现(内部类的公共构造函数现在很模糊),而且获得了更好的语法:

Equality<Person>.CreateComparer(p => p.ID);

请注意,我没有从父类(它是静态的)继承嵌套类。

或者有时我看到自己这样做:

public abstract class Equater<T> : IEqualityComparer<T>
{
    public static Equater<T> Create<TKey>(Func<T, TKey> keySelector)
    {
        return new Impl<TKey>(keySelector);
    }
    public abstract bool Equals(T x, T y);
    public abstract int GetHashCode(T obj);

    class Impl<TKey> : Equater<T>
    {
        readonly Func<T, TKey> keySelector;
        public Impl(Func<T, TKey> keySelector)
        {
            this.keySelector = keySelector;
        }
        public override bool Equals(T x, T y)
        {
            ----
        }
        public override int GetHashCode(T obj)
        {
            ....
        }
    }
}

这里还有一个类似的

public class Accessor<S>
{
    public static Accessor<S, T> Create<T>(Expression<Func<S, T>> memberSelector)
    {
        return new GetterSetter<T>(memberSelector);
    }
    class GetterSetter<T> : Accessor<S, T>
    {
        public GetterSetter(Expression<Func<S, T>> memberSelector) : base(memberSelector)
        {
        }
    }
}
public class Accessor<S, T> : Accessor<S>
{
    Func<S, T> Getter;
    Action<S, T> Setter;
    public bool IsReadable { get; private set; }
    public bool IsWritable { get; private set; }
    public T this[S instance]
    {
        get
        {
            if (!IsReadable)
                throw new ArgumentException("Property get method not found.");
            return Getter(instance);
        }
        set
        {
            if (!IsWritable)
                throw new ArgumentException("Property set method not found.");
            Setter(instance, value);
        }
    }
    protected Accessor(Expression<Func<S, T>> memberSelector) //access not given to outside world
    {
        ----
    }
}

注意,在这两个例子中,我继承了包装类。现在,我不仅得到了前者的好处,而且还可以像这样维护列表:

List<Equater<Person>> { persons with different implementations };

它时不时地帮助我。所以我很想知道这个模式是否有一个名字?

泛型基类包装嵌套的泛型类以减少类型参数规范:此模式是否有名称?

我认为这很像基于抽象工厂模式的类集群模式

我认为你没有遵循任何一种模式。

我想说,通过用一个"Create"方法替换多个"CreateComparer"方法,你只是简化了一个创建方法模式。在某种意义上,你可以说这是一种工厂模式?或者可能是一个Builder模式-我猜这是一个开放的解释?

通过在"Equater"中嵌入"Impl",你遵循了命令模式——封装方法调用,这样调用代码就不知道是如何完成的。

无论如何,对不起,我不能比这更有帮助或给你一个明确的答案!不管怎样,希望它能有所帮助!

正如Bertie正确指出的那样,我在这里可能没有遵循任何一个模式。

我想说,通过将具体实现的实例化委托给CreateComparer方法,我只是简化了对象的创建——它属于创建方法模式。通过拥有一个用于对象实例化的静态函数,它有点像一个工厂模式——特别是这个工厂方法的变体。

通过继承ImplEquater我有点遵循抽象工厂模式-其中Equater是工厂的工厂和Impl是它的实现给Impl本身回来,除了Impl真的不创建任何其他对象(换句话说,Impl不意味着是一个工厂),但获得实例化本身通过构造函数。所以从严格意义上说,它不是抽象工厂模式,但如果Impl可以有一个方法来调用自己的构造函数并返回一个实例,它将更接近于抽象工厂模式。

同样,通过嵌入和隐藏实现细节(嵌套类),暴露的类(父类)向外界显示,就好像它正在做它的工作一样。这就是所谓的委托模式

至于在嵌套的泛型类中隐藏泛型类的实现以使方法调用更容易签名的名称,我认为不存在。即使存在任何名称,它也必须非常特定于语言(或类似的语言),因为涉及到泛型/类型推断等语言结构。Eric Lippert在嵌套类中发现了同样的用法,尽管它与泛型无关,他称之为工厂模式。