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

重构它们的最佳方法是什么,这样我就不会在方法主体中重复本质上相同的逻辑?

之所以不那么简单(在我看来)是因为方法签名略有不同,因为一个人采用(并返回)一个 ' List' 的LedgerSummarys 和另一个LedgerPostingss,并且每个都有不同的属性名称(映射到中的相同性质ExcludedLedgerAccount)。

不幸的是,我不能更改这两个类中的任何一个的属性或使用一个通用接口,例如,因为会延长这个讨论的原因!

我知道答案非常简单(所以我提前道歉)但我现在似乎遇到了程序员的障碍

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 回答