C# 泛型基类包装嵌套泛型类以减少类型参数规范:此模式有名称吗?

C# 泛型基类包装嵌套泛型类以减少类型参数规范:此模式有名称吗?,c#,generics,design-patterns,naming,nested-class,C#,Generics,Design Patterns,Naming,Nested Class,好的,问题的标题远非自明的。我经常看到自己这样做: 发件人: 公共静态类相等 { 公共静态IEqualityComparer创建比较器(Func键选择器) { 返回新的KeyEqualityComparer(钥匙选择器); } 类KeyEqualityComparer:IEqualityComparer { 只读Func键选择器; 公钥平等比较程序(Func密钥选择器) { this.keySelector=keySelector; } 公共布尔等于(TX,TY) { ---- } 公共

好的,问题的标题远非自明的。我经常看到自己这样做:

发件人:

公共静态类相等
{
公共静态IEqualityComparer创建比较器(Func键选择器)
{
返回新的KeyEqualityComparer(钥匙选择器);
}
类KeyEqualityComparer:IEqualityComparer
{
只读Func键选择器;
公钥平等比较程序(Func密钥选择器)
{    
this.keySelector=keySelector;
}
公共布尔等于(TX,TY)
{
----
}
公共int GetHashCode(T obj)
{
....
}
}
}
我做了什么:有一个实现细节
KeyEqualityComparer
,我不得不调用它:

new KeyEqualityComparer<Person, int>(p => p.ID);
newkeyequalitycomparer(p=>p.ID);
通过将其嵌套为私有类,我不仅隐藏了实现(内部类的公共构造函数现在不太清楚),而且得到了更好的语法:

Equality<Person>.CreateComparer(p => p.ID);
Equality.CreateComparer(p=>p.ID);
请注意,我没有从父类继承嵌套类(它是静态的)

有时我看到自己:

公共抽象类等价器:IEqualityComparer
{
公共静态等价器创建(Func keySelector)
{
返回新的Impl(keySelector);
}
公共抽象布尔等于(tx,ty);
公共摘要int GetHashCode(T obj);
类Impl:equaler
{
只读Func键选择器;
公共Impl(Func键选择器)
{
this.keySelector=keySelector;
}
公共覆盖布尔等于(TX,TY)
{
----
}
公共覆盖int GetHashCode(T obj)
{
....
}
}
}
另一个类似的

公共类访问器
{
公共静态访问器创建(表达式成员选择器)
{
返回新的GetterSetter(memberSelector);
}
类GetterSetter:访问器
{
公共GetterSetter(表达式成员选择器):base(成员选择器)
{
}
}
}
公共类访问器:访问器
{
Func吸气剂;
行动设定者;
公共bool是可读取的{get;private set;}
public bool可写{get;private set;}
这是一个公开的例子
{
得到
{
如果(!IsReadable)
抛出新ArgumentException(“未找到属性获取方法”);
返回Getter(实例);
}
设置
{
如果(!可写)
抛出新ArgumentException(“未找到属性集方法”);
Setter(实例、值);
}
}
受保护的访问器(Expression memberSelector)//未向外部世界提供访问权限
{
----
}
}
注意,在这两种情况下,我继承了包装类。因此,现在我不仅得到了前者的好处,而且我还可以维护如下列表:

List<Equater<Person>> { persons with different implementations };
列出{有不同实现的人};

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

我想你没有遵循过任何一种模式

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

通过在“equaler”中嵌入“Impl”,您在某种程度上遵循了命令模式——封装方法调用,这样您的调用代码就不知道它是如何完成的


不管怎样,对不起,我帮不了你什么忙,也不能给你一个明确的答案!不管怎样,希望能有帮助

正如伯蒂正确指出的那样,我可能没有遵循任何一种模式

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

通过从
equaler
继承
Impl
,我遵循了一种模式,其中
equaler
是工厂的工厂,
Impl
是它的实现,将
Impl
自身返回,除了
Impl
实际上没有创建任何其他对象(换句话说,
Impl
并不意味着它是一个工厂),而是通过构造函数来实例化它自己。所以严格意义上说,它不是抽象的工厂模式,但是如果
Impl
能够有一个方法来调用它自己的构造函数并返回一个实例,那么它将更接近

同样,通过嵌入和隐藏实现细节(嵌套类本身),公开的类(父类)向外部世界假装它正在做自己的工作


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

我认为这与基于抽象工厂模式的情况非常相似。

很抱歉,我编辑了答案,因为我认为我没有使用命令或builder模式。请随意编辑,如果我的answer@nawfal:虽然我们鼓励编辑答案以改进它们,但请记住,在这样做时,你应该尊重原作者的写作。你的编辑似乎对Bertie的原始答案改变太多了,尤其是你的编辑
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 };