C# ';无法从用法';

C# ';无法从用法';,c#,generics,inheritance,type-conversion,C#,Generics,Inheritance,Type Conversion,我在泛型和继承方面遇到了一些问题。我有一个名为CriteriaBase的抽象类,其任务是确定实体T是否与任何子类中定义的标准匹配。子类必须实现一个方法,该方法返回表示标准的Func。当我尝试对函数使用泛型时,问题就出现了。希望一些代码能说明我的问题 public abstract class CriteriaBase<T, U> where T : ICrossoverable where U : IChromosome { protected abstrac

我在泛型和继承方面遇到了一些问题。我有一个名为
CriteriaBase
的抽象类,其任务是确定实体
T
是否与任何子类中定义的标准匹配。子类必须实现一个方法,该方法返回表示标准的
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);
    }
}
问题出在
GetNumberOfCriteriaMatches()
方法中。选项2是我最初编写代码的方式,但我得到的编译错误如下所示。如果我使用选项1,那么代码会编译,但这意味着当我重写子类中的
条件
时,我必须使用
IChromosome
,而不是
MatchDay
,这不起作用(我需要访问
MatchDay
的特定功能)。在我看来,选项1和选项2是等价的。选项2只是将
IChromosome
替换为泛型类型
U
,该泛型类型仅限于实现
IChromosome
的类

我想要达到的目标可能吗?如果是,我遗漏了什么/误解了什么?如果没有,我应该如何处理这个问题

为了完整性(包括在最后,因为我不确定它对这个问题有多大帮助),这里是我目前用于
T
seasure
)和
U
MatchDay
)的两个实体

公共课季:ICrossoverable
{
私有只读IEnumerable\u matchDays;
公共赛季(IEnumbered matchDays)
{
_比赛日=比赛日;
}
公共比赛日数
{
获取{return\u matchDays;}
}
//可分离实现
公共可数染色体
{
获取{return\u matchDays;}
}
}
公共类比赛日:IChromosome
{
私人只读国际周;
专用只读列表_装置;
公共比赛日(国际周,列出固定装置)
{
_周=周;
_固定装置=固定装置;
}
//为了简洁起见,删除了一些代码
公共数字固定装置
{
获取{return\u fixtures;}
}
//染色体执行
公共可数基因
{
获取{return Fixtures;}
}
}

您应该在标准库定义的U之前使用
中的关键字
。大概是这样的:

public abstract class CriteriaBase<T, in U>
    where T : ICrossoverable
    where U : IChromosome
公共抽象类标准库
其中T:icroscoverable
其中U:IChromosome
更新。这是行不通的。 尝试显式指定类型

private int GetNumberOfCriteriaMatches(T season)
{
 ....
    return season.Chromosomes.Count<IChromosome>(Criteria);
}
private int GetNumberOfCriteriaMatches(T季节)
{
....
回归季节。染色体。计数(标准);
}

这就是问题所在:

public IEnumerable<IChromosome> Chromosomes

。。。或者您可以更改
染色体
以返回
IEnumerable
。不幸的是,我们无法真正判断这是否是一个有效的答案,因为我们不知道如何声明
icrosoverable
。也许您应该在元素类型中将
icrosoverable
设置为generic?

您使用的.net framework版本是什么?.net版本4-完整版本,而不是客户端配置文件。答案是否因版本而异?如果有意思的话,可以使用Visual Studio 2010。委托协方差和逆变在4.0版的c#中工作。执行此操作时,我收到一个编译器错误,提示“变量类型参数只能在接口或委托中声明”。三个问题:在
中添加
有什么作用,这个错误意味着什么,为什么不起作用?谢谢我忘记了这只适用于代理和接口。好啊然后尝试显式指定计数(条件),现在出现不同的错误参数类型“System.Func”不可分配给参数类型“System.Func”。几乎就好像“U:IChromosome”不存在一样!现在在哪里?我没有新的想法。。。试着在这里召唤乔恩·斯基特。啊哈!这就把事情弄清楚了。我认为真正的解决办法在于你的最后一句话——使
icrosoverable
generic。明天我将尝试此功能并报告。根据建议,我制作了
icrosoverable
generic,解决了我的问题。密码在里面。我将iCrossoberable重命名为IOrganism,因为它更符合遗传算法术语。可以找到“CriteriaBase”的实现。感谢您提出的各种各样的建议。
private int GetNumberOfCriteriaMatches(T season)
{
 ....
    return season.Chromosomes.Count<IChromosome>(Criteria);
}
public IEnumerable<IChromosome> Chromosomes
return season.Chromosomes.Cast<U>().Count(Criteria);