Stu*_*ole 5 c# generics inheritance type-conversion
我在使用泛型和遗传方面遇到了一些麻烦.我有一个抽象类CriteriaBase
,其作用是确定实体是否T
与任何子类中定义的条件匹配.子类必须实现一个返回Func
表示标准的方法.当我尝试使用泛型时,问题就出现了Func
.希望一些代码能说明我的问题.
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);
}
}
Run Code Online (Sandbox Code Playgroud)
我的意图是该CriteriaBase
课程应该是通用的,完全可以重复使用.
一个示例子类:
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; }
}
}
Run Code Online (Sandbox Code Playgroud)
问题出在GetNumberOfCriteriaMatches()
方法上.选项2是我最初编写代码的方式,但是我得到了列出的编译错误.如果我使用选项1然后代码编译但这意味着当我Criteria
在子类中重写时,我必须使用IChromosome
而不是MatchDay
哪个不起作用(我需要访问a的特定功能MatchDay
).简单来说,选项1和2是等价的.选项2简单地替换IChromosome
为泛型类型U
,该类型仅限于实现的类IChromosome
.
我正在努力实现的目标是什么?如果是这样,我有什么遗漏/误解?如果没有,我该如何处理这个问题?
为了完整性(包括在最后,因为我不确定它对问题有多大帮助),这里是我目前用于T
(Season
)和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; }
}
}
Run Code Online (Sandbox Code Playgroud)
这是问题所在:
public IEnumerable<IChromosome> Chromosomes
Run Code Online (Sandbox Code Playgroud)
你只是声明你正在返回一系列IChromosome
值.您的标准需要MatchDay
值.您碰巧知道它实际上返回了一系列MatchDay
值,但编译器却没有.
您可以Cast<>
在执行时使用它来检查:
return season.Chromosomes.Cast<U>().Count(Criteria);
Run Code Online (Sandbox Code Playgroud)
...或者你可以改变Chromosomes
以返回IEnumerable<MatchDay>
.不幸的是,我们无法确定这是否是一个有效的答案,因为我们不知道如何ICrossoverable
宣布.也许你应该ICrossoverable
在元素类型中制作泛型?