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