鉴于这种私人方法:
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
的{{1}}取得(并返回) s和其他LedgerSummary
,并且每个都有不同的属性名称(映射到LedgerPostings
中的相同属性)。
不幸的是,我无法更改这两个类中的任何一个属性或使用通用接口,例如,出于延长此话语的原因!
我知道答案非常简单(所以我提前道歉)但我现在似乎有一个programmer's block。
答案 0 :(得分: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);
答案 1 :(得分: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);
答案 2 :(得分:0)
除非LedgerSummary和LedgerPosting共享一个共同的基类来完成你需要的所有工作(在这种情况下你可以使用泛型),否则你无法做太多。
在C ++中,你可以使用模板(甚至是typedef)来获得一个很好的解决方案,但不能在C#或java中使用...除非你想使用代码生成器。