'无法从使用中推断出类型参数'

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)

Jon*_*eet 8

这是问题所在:

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在元素类型中制作泛型?

  • 正如所建议的那样,我制作了"ICrossoverable"泛型,解决了我的问题.代码在[my Github repository](https://github.com/hungryhippo2312/GeneticAlgorithm)中.我将ICrossoverable重命名为IOrganism,因为它更符合遗传算法术语.可以在[另一个Github存储库]中找到`CriteriaBase <TOrganism,TChromosome>的实现(https://github.com/hungryhippo2312/FixtureGenerator/blob/master/FixtureGenerator/Criteria/SuperSundayCriteria.cs).感谢多种多样的建议. (2认同)