【发布时间】:2013-04-18 11:57:57
【问题描述】:
好的问题标题远非不言自明。我经常看到自己这样做:
来自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)
{
....
}
}
}
我做了什么:有一个实现细节 KeyEqualityComparer<T, K> 我必须调用:
new KeyEqualityComparer<Person, int>(p => p.ID);
通过将其嵌套为私有类,我不仅隐藏了实现(内部类的公共构造函数现在已经模糊了),而且获得了更好的语法:
Equality<Person>.CreateComparer(p => p.ID);
请注意,我没有从父类(静态)继承嵌套类。
或者有时我看到自己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)
{
....
}
}
}
另一个类似的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
{
----
}
}
请注意,在这两种情况下,我从包装类继承。所以现在我不仅得到了前者的好处,而且还可以维护这样的列表:
List<Equater<Person>> { persons with different implementations };
它不时帮助我。 所以我很想知道这种模式是否有名称?
【问题讨论】:
标签: c# generics design-patterns naming nested-class