Ho problemi con generici ed ereditarietà. Ho una classe astratta chiamata CriteriaBase
il cui compito è determinare se un'entità T
corrisponde ai criteri definiti in qualsiasi sottoclasse. Le sottoclassi devono implementare un metodo che restituisce un Func
che rappresenta i criteri. Il problema sorge quando provo a utilizzare i generici per lo Func
. Spero che qualche codice possa illustrare il mio problema.'Gli argomenti di tipo non possono essere dedotti dall'uso'
public abstract class CriteriaBase<T, U>
where T : ICrossoverable
where U : IChromosome
{
protected abstract Func<U, bool> Criteria { get; }
//some code removed for brevity
private int GetNumberOfCriteriaMatches(T season)
{
//1. works
//Func<IChromosome, bool> predicate = c => c.Genes == null;
//return season.Chromosomes.Count(predicate);
//2. doesn't work - The type arguments for method 'int
//System.Linq.Enumerable.Count<TSource>(this IEnumerable<TSource>,
//Func<TSource, bool>)'
//cannot be inferred from the usage. Try specifying the type arguments
//explicitly.
return season.Chromosomes.Count(Criteria);
}
}
La mia intenzione è che la classe CriteriaBase
dovrebbe essere generico e completamente riutilizzabile.
Un esempio sottoclasse:
public class TopTeamsPlayingEachOtherCriteria : CriteriaBase<Season, MatchDay>
{
//some code removed for brevity
protected override Func<MatchDay, bool> Criteria
{
get { return matchDay =>
matchDay.Fixtures.Count(
fixture =>
fixture.HomeTeam.TableGrouping.Ordering == 1
&& fixture.AwayTeam.TableGrouping.Ordering == 1) > 1; }
}
}
Il problema è nel metodo GetNumberOfCriteriaMatches()
. L'opzione 2 è come ho originariamente scritto il codice, ma ottengo l'errore di compilazione come elencato. Se utilizzo l'opzione 1, il codice viene compilato ma significa che quando eseguo l'override di Criteria
nella sottoclasse, devo utilizzare IChromosome
anziché MatchDay
che non funziona (devo accedere a funzioni specifiche di MatchDay
). Nella mia mente semplice, le opzioni 1 e 2 sono equivalenti. L'opzione 2 sostituisce semplicemente IChromosome
con un tipo generico U
che è limitato a una classe che implementa IChromosome
.
È ciò che sto cercando di ottenere possibile? In caso affermativo, cosa mi manca/incomprensione? In caso contrario, come dovrei affrontare questo problema?
Per completezza (incluso alla fine, come io non sono sicuro di quanto si aiuta con la domanda), ecco le due entità che sono attualmente in uso per la T
(Season
) e U
(MatchDay
).
public class Season : ICrossoverable
{
private readonly IEnumerable<MatchDay> _matchDays;
public Season(IEnumerable<MatchDay> matchDays)
{
_matchDays = matchDays;
}
public IEnumerable<MatchDay> MatchDays
{
get { return _matchDays; }
}
//ICrossoverable implementation
public IEnumerable<IChromosome> Chromosomes
{
get { return _matchDays; }
}
}
public class MatchDay : IChromosome
{
private readonly int _week;
private readonly List<Fixture> _fixtures;
public MatchDay(int week, List<Fixture> fixtures)
{
_week = week;
_fixtures = fixtures;
}
//some code removed for brevity
public IEnumerable<Fixture> Fixtures
{
get { return _fixtures; }
}
//IChromosome implementation
public IEnumerable<IGene> Genes
{
get { return Fixtures; }
}
}
Quale versione di.quadro di rete usi? –
. NET versione 4: la versione completa non è il profilo del client. La risposta è diversa a seconda della versione? Utilizzando Visual Studio 2010 è interessante. – Stu
La covarianza e la contravarianza dei delegati funziona in C# dalla versione 4.0 –