Ho implementato il modello di specifica e volevo cambiarlo per supportare la controvarianza. Tuttavia è sorto un problema interessante.Contravarianza e sovraccarico dell'operatore
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));
}
}
questo lavoro come ci si può aspettare
new Specification<DerivedClass>((x) => true) & new Specification<BaseClass> ((x) => true)
ma se invertire l'ordine di argomenti non più a compilare
new Specification<BaseClass>((x) => true) & new Specification<DerivedClass>((x) => true)
capisco perché questo accade, ma la mia domanda è - C'è un modo per avere entrambi funzionanti?
EDIT:
Ho già provato a definire operatore & con ordine inverso o params come quello
public static Specification<T> operator &(ISpecification<T> left, Specification<T> right)
{
return new Specification<T>((x) => left.Predicate(x) && right.Predicate(x));
}
ma sto ottenendo errore del compilatore chiamata ambiguo tra i due operatori. Sto usando .NET 4.5
netfiddle: https://dotnetfiddle.net/GB66UN
L'ho già provato ma sto ricevendo una chiamata ambigua tra entrambi gli operatori – ekalchev
Interessante, potrebbe essere una mancata corrispondenza della versione. Ho questo lavoro in LINQPad 5, che si rivolge a .NET 4.6 e utilizza C# 6. So che l'implementazione per la risoluzione di sovraccarico ha visto le modifiche. –
LINQPad 4 (.NET 4.5) accetta anche questo. Puoi mostrare il codice completo che dà l'errore - in particolare, la chiamata che fallisce dopo che entrambi i sovraccarichi sono a posto? –