Как и любой рефакторинг, просто отсеивать по кусочкам. Во-первых, вместо foreach
просто используйте Sum()
, например, так.
return ListOfCheques.Sum(c =>
{
var exchangeRate = (from exc in c.ExchangeRates
where exc.Type == EnumExchangeRate.ForCheque
select exc).FirstOrDefault();
return c.NetAmount * (exchangeRate ?? new ExchangeRate(){ Rate = 1 }).Rate;
});
(было бы неплохо, если бы значением по умолчанию для свойства ExchangeRate.Rate было 1)
Я бы переписал функцию exchangeRate в простой формат. Вы уверены, что хотите FirstOrDefault
, а не SingleOrDefault
?
var exchangeRate = c.ExchangeRates.
FirstOrDefault(ex => ex.Type == EnumExchangeRate.ForCheque);
и затем это может быть заменено на первое утверждение, оставляя конечный продукт ниже.
Один лайнер, если хотите, чтобы он был!
return ListOfCheques.Sum(c => c.NetAmount *
(c.ExchangeRates.FirstOrDefault(ex => ex.Type == EnumExchangeRate.ForCheque)
?? new ExchangeRate() { Rate = 1 }).Rate);
редактировать
Разъяснение по поводу новый ExchangeRate ()
Вместо того, чтобы делать != null ? (amount * rate) : (rate)
, я предпочитаю объединять объект ExchangeRate
с новым таким объектом с Rate = 1. Я думаю, что это обеспечивает более гладкую и чистую часть кода. Я настоятельно рекомендую вам сделать ставку по умолчанию равной 1,0, а затем вы можете просто объединиться с new ExchangeRate()
, без необходимости устанавливать свойство Rate.
Чтобы установить значение по умолчанию для Rate
в новом объекте ExchangeRate, просто поместите инициализатор внутри конструктора
class ExchangeRate
{
public ExchangeRate()
{
this.Rate = 1.0;
}
// other stuff
}