1

このプライベートメソッドを考えると:

private static IEnumerable<LedgerSummary> FilterLedgers(IList<LedgerSummary> ledgers, List<ExcludedLedgerAccount> excludedLedgerAccounts)
{
    var excludedLedgerEntries = ledgers.Where(x => excludedLedgerAccounts.Any(y => y.LedgerAccount == x.LedgerAccount)).ToList();

    var filteredLedgers = ledgers.Except(excludedLedgerEntries).ToList();

    // do some more filtering

    return filteredLedgers;
}

そしてこれ:

private static IEnumerable<LedgerPosting> FilterLedgers(IList<LedgerPosting> ledgers, List<ExcludedLedgerAccount> excludedLedgerAccounts)
{
    var excludedLedgerEntries = ledgers.Where(x => excludedLedgerAccounts.Any(y => y.LedgerAccount == x.DistributionAccountLedgerAccount)).ToList();

    var filteredLedgers = ledgers.Except(excludedLedgerEntries).ToList();

    // do some more filtering

    return filteredLedgers;
}

メソッド本体で本質的に同じロジックを繰り返さないように、それらをリファクタリングするための最良の方法は何ですか?

(私の考えでは)それほど単純ではない理由は、メソッドのシグネチャが、 sと他のsの' List'を取得(および返す)する点でわずかに異なり、これらのそれぞれが異なるプロパティ名を持っているためです(の同じプロパティ。LedgerSummaryLedgerPostingsExcludedLedgerAccount

残念ながら、たとえば、この談話が長くなる理由で、これら2つのクラスのいずれかのプロパティを変更したり、共通のインターフェイスを使用したりすることはできません。

私は答えが本当に簡単であることを知っています(それで私は前もって謝罪します)が、私はその瞬間にプログラマーのブロックを持っているようです。

4

3 に答える 3

3

このようなものを試してください(現在VSを持っていない、少しデバッグが必要な場合があります)

private static IEnumerable<T> FilterLedgers<T> FilterLedgers(
    IList<T> ledgers, 
    List<ExcludedLedgerAccount> excludedLedgerAccounts,
    Func<T, ExcludedLedgerAccount, bool> selector)
{
    var excludedLedgerEntries = ledgers.Where(x => excludedLedgerAccounts.Any(y => selector(x, y)).ToList();

    var filteredLedgers = ledgers.Except(excludedLedgerEntries).ToList();

    // do some more filtering

    return filteredLedgers;
}

そしてそれを使用してください:

IEnumerable<LedgerSummary> result = FilterLedgers<LedgerSummary>(input, exclude, (i, e) => i.LedgerAccount == e.LedgerAccount);

IEnumerable<LedgerPosting> result = FilterLedgers<LedgerSummary>(input, exclude, (i, e) => i.LedgerAccount == e.DistributionAccountLedgerAccount);
于 2012-11-26T11:50:38.793 に答える
1

Any拡張メソッドで使用している述語を抽出できます。

private static IEnumerable<LedgerSummary> FilterLedgersImpl(IEnumerable<LedgerSummary> ledgers, Func<LedgerSummary, LedgerAccount, bool> predicate)
{
    var excludedLedgerEntries = 
        ledgers
           .Where(x => excludedLedgerAccounts.Any(y => predicate(x, y)))
           .ToList();

    var filteredLedgers = ledgers.Except(excludedLedgerEntries).ToList();

    // do some more filtering

    return filteredLedgers;
}

そして、このヘルパーメソッドを直接使用できます。

var list1 = FilderLedgersImpl(ledgers, (x, y) => y.LedgerAccount == x.LedgerAccount);

var list2 = FilderLedgersImpl(ledgers, (x, y) => y.LedgerAccount == x.DistributionAccountLedgerAccount);
于 2012-11-26T11:51:22.863 に答える
0

LedgerSummaryとLedgerPostingが、必要なすべての作業を実行する共通の基本クラスを共有しない限り(この場合、ジェネリックを使用できます)、これで多くのことを行うことはできません。

C ++では、優れたソリューションとしてテンプレート(またはtypedef)を使用できますが、コードジェネレーターを使用する場合を除いて、C#やJavaでは使用できません。

于 2012-11-26T11:52:40.133 に答える