c# - “无法从用法中推断出类型参数”

标签 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);
    }
}

我的意图是 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; }
    }
}

问题出在 GetNumberOfCriteriaMatches() 方法中。选项 2 是我最初编写代码的方式,但出现了所列的编译错误。如果我使用选项 1,那么代码会编译,但这意味着当我在子类中覆盖 Criteria 时,我必须使用 IChromosome 而不是 MatchDay 不起作用(我需要访问 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; }
    }
}

最佳答案

这就是问题所在:

public IEnumerable<IChromosome> Chromosomes

只是声明你要返回一个 IChromosome 的序列值。你的标准是MatchDay值。 碰巧知道它实际上返回了一个序列 MatchDay值,但编译器没有。

你可以使用 Cast<>在执行时检查:

return season.Chromosomes.Cast<U>().Count(Criteria);

... 或者您可以更改 Chromosomes返回 IEnumerable<MatchDay> .不幸的是,我们无法真正判断这是否是一个有效答案,因为我们不知道如何 ICrossoverable被宣布。也许你应该制作 ICrossoverable元素类型中的泛型?

关于c# - “无法从用法中推断出类型参数”,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15868044/

相关文章:

c# - 我可以阻止 .net 4.0 对单引号进行编码吗?

c# - 如何判断文件夹是否打开?

generics - 如何使用泛型类型参数定义变量?

java - 为什么我们不能在泛型类中创建一个 "Concrete"类数组?

java - 返回一个 Class 实例及其泛型

Scala - 推断为错误类型,导致类型不匹配?

c# - 如何确定为接口(interface)的不同实现调用哪个存储库?

c# - 带有滚动背景图像的 ListView

python - py.test - 如何继承其他测试

java - 为什么InputStream类可以被实例化呢?不是抽象类吗?