Ich habe Spezifikation Muster Implementierung und ich wollte es ändern, um Kontravarianz zu unterstützen. Es entstand jedoch ein interessantes Problem.Kontravarianz und Operator Überlast
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));
}
}
diese Arbeit, wie Sie
new Specification<DerivedClass>((x) => true) & new Specification<BaseClass> ((x) => true)
erwarten würde, aber wenn ich die Reihenfolge Argument umkehren nicht kompiliert es nicht mehr
new Specification<BaseClass>((x) => true) & new Specification<DerivedClass>((x) => true)
Ich verstehe, warum dies geschieht, aber meine Frage ist - Gibt es eine Möglichkeit, beides zu haben?
EDIT:
Ich habe bereits versucht Operator zu definieren & mit umgekehrter Reihenfolge oder params wie die
public static Specification<T> operator &(ISpecification<T> left, Specification<T> right)
{
return new Specification<T>((x) => left.Predicate(x) && right.Predicate(x));
}
aber ich bin immer mehrdeutig Aufruf Compilerfehler zwischen den beiden Betreibern. Ich verwende .NET 4.5
netfiddle: https://dotnetfiddle.net/GB66UN
Ich habe das schon versucht, aber ich bekomme mehrdeutigen Anruf zwischen beiden Operatoren – ekalchev
Interessant, das kann eine Versionskonflikt sein. Ich habe dies in LINQPad 5 funktioniert, die .NET 4.6 zielt und C# 6 verwendet. Ich kenne die Implementierung für Überladungsauflösung sah Änderungen. –
LINQPad 4 (.NET 4.5) akzeptiert dies auch. Können Sie den vollständigen Code anzeigen, der den Fehler verursacht - insbesondere den Aufruf, der nach dem Auftreten beider Überladungen fehlschlägt? –