eka*_*hev 5 c# generics c#-4.0
我有规范模式实现,我想改变它以支持逆变.然而,出现了有趣的问题.
public interface ISpecification<in T>
{
Func<T, bool> Predicate { get; }
bool IsSatisfiedBy(T entity);
}
public class Specification<T> : ISpecification<T>
{
public Specification(Func<T, bool> predicate)
{
this.Predicate = predicate;
}
public Func<T, bool> Predicate
{
get;
private set;
}
public bool IsSatisfiedBy(T x)
{
return Predicate.Invoke(x);
}
public static Specification<T> operator &(Specification<T> left, ISpecification<T> right)
{
return new Specification<T>((x) => left.Predicate(x) && right.Predicate(x));
}
}
Run Code Online (Sandbox Code Playgroud)
你可以期待这项工作
new Specification<DerivedClass>((x) => true) & new Specification<BaseClass> ((x) => true)
Run Code Online (Sandbox Code Playgroud)
但如果我颠倒了参数的顺序,它就不再编译了
new Specification<BaseClass>((x) => true) & new Specification<DerivedClass>((x) => true)
Run Code Online (Sandbox Code Playgroud)
我理解为什么会发生这种情况,但我的问题是 - 有没有办法兼顾两者?
编辑:
我已经尝试使用相反的顺序或params来定义运算符
public static Specification<T> operator &(ISpecification<T> left, Specification<T> right)
{
return new Specification<T>((x) => left.Predicate(x) && right.Predicate(x));
}
Run Code Online (Sandbox Code Playgroud)
但我在两个运营商之间调用编译器错误模糊不清.我使用的是.NET 4.5
netfiddle:https://dotnetfiddle.net/GB66UN
是的 - 再次为其他参数顺序执行此操作.
public static Specification<T> operator &(ISpecification<T> left, Specification<T> right)
{
return new Specification<T>((x) => left.Predicate(x) && right.Predicate(x));
}
Run Code Online (Sandbox Code Playgroud)
运算符重载不要求第一个参数是封闭类型,只需要其中一个参数.
正如@DStanley指出的那样,即使这会在表单调用时失败
new Specification<DerivedClass>((x) => true) & new Specification<DerivedClass>((x) => true);
Run Code Online (Sandbox Code Playgroud)
所以我们再次这样做,对于这个特定的参数组合:
public static Specification<T> operator &(Specification<T> left, Specification<T> right)
{
return new Specification<T>((x) => left.Predicate(x) && right.Predicate(x));
}
Run Code Online (Sandbox Code Playgroud)