5

ジェネリックと継承に問題があります。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代わりにMatchDaywhich を使用する必要があることを意味します (の特定の機能にアクセスする必要がありますMatchDay)。私の単純な考えでは、オプション 1 と 2 は同等です。オプション 2 は、単にを実装するクラスに制限されIChromosomeたジェネリック型に置き換えます。UIChromosome

私が達成しようとしていることは可能ですか?もしそうなら、私は何が欠けている/誤解していますか? そうでない場合、この問題にどのようにアプローチすればよいですか?

完全を期すために(質問にどれだけ役立つかわからないため、最後に含めます)、現在TSeason)とUMatchDay)に使用している2つのエンティティを次に示します。

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; }
    }
}
4

2 に答える 2

3

inCriteriaBase 定義では、U の前にキーワードを使用する必要があります。このようなもの:

public abstract class CriteriaBase<T, in U>
    where T : ICrossoverable
    where U : IChromosome

更新します。効果がないでしょう。タイプを明示的に指定してみてください

private int GetNumberOfCriteriaMatches(T season)
{
 ....
    return season.Chromosomes.Count<IChromosome>(Criteria);
}
于 2013-04-07T21:41:33.060 に答える