通用基类包装嵌套泛型类以减少类型参数规范:此模式是否有名称? [英] Generic base class wraps nested generic class to reduce type argument specification: Is there a name for this pattern?

查看:122
本文介绍了通用基类包装嵌套泛型类以减少类型参数规范:此模式是否有名称?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

确定问题标题远不是不言自明的。我经常看到自己这样做:



这个答案

  public static class Equality< T> 
{
public static IEqualityComparer< T> CreateComparer< K>(Func< T,K> keySelector)
{
返回新的KeyEqualityComparer< K>(keySelector);
}



class KeyEqualityComparer< K> :IEqualityComparer< T>
{
readonly Func< T,K>的KeySelectors;

public KeyEqualityComparer(Func< T,K> keySelector)
{
this.keySelector = keySelector;
}

public bool等于(T x,T y)
{
----
}

public int GetHashCode(T obj)
{
....
}
}
}

我做了什么:有一个实现细节 KeyEqualityComparer< T,K> 我必须调用:新的KeyEqualityComparer< Person,int>(p => p.ID); p>

 

通过将其嵌套为私有类,不仅隐藏了实现(内部的公共构造函数类现在是模糊的),但是得到一个更好的语法:

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

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



或者有时我看到自己

  public抽象类Equater< T> :IEqualityComparer< T> 
{
public static Equater< T>创建< TKey>(Func< T,TKey> keySelector)
{
return new Impl< TKey>(keySelector);
}

public abstract bool等于(T x,T y);

public abstract int GetHashCode(T obj);



class Impl< TKey> :Equater< T>
{
readonly Func< T,TKey>的KeySelectors;

public Impl(Func< T,TKey> keySelector)
{
this.keySelector = keySelector;
}

public override bool等于(T x,T y)
{
----
}

public override int GetHashCode(T obj)
{
....
}
}
}

另一个类似的此处

  public class Accessor< S> 
{
public static Accessor< S,T>创建< T>(表达式< Func< S,T>> memberSelector)
{
返回新的GetterSetter< T>(memberSelector);
}

class GetterSetter< T> :访问者< S,T>
{
public GetterSetter(Expression< Func< S,T>> memberSelector):base(memberSelector)
{

}
}
}

public class Accessor< S,T> :访问者< S>
{
Func< S,T>吸气;
动作< S,T>二传手;

public bool IsReadable {get;私人集合}
public bool IsWritable {get;私人集合
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(表达式< Func< S,T>> memberSelector)//访问未给予外界
{
----
}

}

请注意,这两种情况我从包装类继承。所以现在,我不仅得到了前者的好处,而且还可以保留这样的列表:

 列表< Equater<人>> {具有不同实现的人}; 

它帮助我不时。 所以我很好奇,知道这个模式是否有名字?

解决方案

正确地Bertie指出,我可能没有按照这里的任何一个模式。



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



通过继承 Impl Equater 我有一种遵循抽象工厂模式,其中 Equater 是工厂的工厂,并且 Impl 是它的实现,给出 Impl 本身,除了 Impl 真的没有创建任何其他对象(换句话说, Impl 不是一个工厂),而是通过构造函数。所以在严格意义上说,它不是抽象工厂模式,但是如果 Impl 可以有一个方法调用自身的构造函数并返回一个实例, p>

同样通过嵌入和隐藏实现细节(这样的嵌套类),暴露的类(父类)会像外部世界一样伪造成外部世界。这就是所谓的授权模式



只要在嵌套泛型类中隐藏实现泛型类以便方便调用的简单签名的名称就是我不认为存在的一个。即使有任何名称存在,它必须是非常具体的语言(或类似的语言),因为语言构造像泛型/类型推理等涉及。 Eric Lippert在嵌套类 here 中发现了相同的用法,尽管它不是泛型相关的,他称之为Factory模式。


Ok question title is far from being self-explanatory. I see myself doing this often:

From this answer:

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

What did I do: There is an implementation detail KeyEqualityComparer<T, K> which I had to call:

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

By nesting it as a private class, not only did I hide the implementation (the public constructor of internal class is obscure now), but got a better syntax:

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

Note here that I haven't inherited nested class from the parent class (which is static).

Or sometimes I see myself doing this:

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

Another similar one here

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

}

Note that in these two cases I inherited from wrapping class. So now not only did I get the benefits of the former but I can also maintain a list like this:

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

Its helping me from time to time. So I'm curious to know if there is a name for this pattern?

解决方案

As rightly pointed out by Bertie, I might have not followed any one pattern here.

I would say that by delegating the instantiation of concrete implementation to CreateComparer method, I have just simplified the object creation - which comes under Creation Method patterns. By having a static function for object instantiation, it was sort of a factory pattern - specifically this variant of Factory Method.

By inheriting Impl from Equater I have sort of followed the Abstract Factory pattern - where Equater is factory of factory and Impl is its implementation to give Impl itself back, except that Impl is really not creating any other object (in other words Impl is not meant to be a factory), but getting instantiated itself via constructor. So in strict sense, its not Abstract Factory pattern, but it will be closer to if Impl can have a method to call the constructor of itself and return back an instance.

Also by embedding and hiding the implementation detail (the nested classes as such), the exposed class (parent class) fakes to outside world as if it is doing it's job. It's what is called Delegation Pattern

As far as a name for hiding implementation of a generic class in a nested generic class to give easier signature for method calls is concerned I don't think there exist one. Even if any name existed, it has to be very specific to the language (or similar languages) since language constructs like generics/type inference etc are involved. Eric Lippert finds the same use in nested classes here although its not generics related, where he calls it Factory pattern.

这篇关于通用基类包装嵌套泛型类以减少类型参数规范:此模式是否有名称?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆