Decimal.TryParse в запросе LINQ - как использовать параметр out и избежать повторного преобразования - PullRequest
0 голосов
/ 21 февраля 2019

Я использую запрос LINQ to XML, чтобы пройти через файл XML и собрать те узлы, где баланс положительный.XML может иметь пустой узел баланса или содержать содержимое, которое не может быть преобразовано в десятичное, поэтому у меня есть проверки, чтобы пропустить такие значения.Одна из проверок использовала decimal.TryParse(), чтобы увидеть, можно ли преобразовать содержимое узла баланса в десятичное.Если он может быть преобразован, у меня есть пункт «Где», который выполняет преобразование.

Структура XML:

<Invoice>
...
  <balance>Could be any string here or empty</balance>
...
</Invoice>

Код:

decimal convertedDecimalButUnused;
var resultsWithPositiveBalance = xml.Descendants("Invoice")
.Where(x => !x.Element("balance").IsEmpty);
.Where(x => Decimal.TryParse(x.Element("balance").Value, out convertedDecimalButUnused))
.Where(x => Convert.ToDecimal(x.Element("balance").Value) > 0);

Мой вопрос:Можно ли использовать параметр out в decimal.TryParse() вместо выполнения десятичного преобразования во второй раз?

Ответы [ 3 ]

0 голосов
/ 21 февраля 2019

Да, вы можете сделать это:

decimal convertedDecimalButUnused;
var resultsWithPositiveBalance = xml.Descendants("Invoice")
.Where(x => !x.Element("balance").IsEmpty);
.Where(x => Decimal.TryParse(x.Element("balance").Value, out convertedDecimalButUnused) && convertedDecimalButUnused > 0);

Вы можете объединить несколько утверждений вместе внутри функции Where, используя &&, что равно AND.

0 голосов
/ 22 февраля 2019

Попробуйте написать метод расширения утилиты, который преобразует XElement в десятичную.В этом случае вы можете рассматривать недесятичные значения как ноль, так как вас интересуют только положительные значения.Если вы хотите провести различие между действительным значением 0 и недесятичным значением, то метод может возвратить нулевое десятичное значение.

public static class UtilityExtensions {
    // return decimal? to differentiate between real zero and non-decimal values
    public static decimal ToDecimal(this XElement element){
        if(element == null || element.IsEmpty) return 0; // return null for decimal?
        decimal value;
        // if you can use C# 7, code can be more succinct with inline declaration
        return Decimal.TryParse(element.Value, out value) ? value : 0; // return null instead of 0 for decimal?
    }
}

Теперь ваш LINQ намного проще.Это также будет обрабатывать случай, когда отсутствует сам элемент «balance».

var resultsWithPositiveBalance = xml.Descendants("Invoice")
         .Where(x => !x.Element("balance").ToDecimal() > 0);

В случае, если вы в конечном итоге используете decimal? версию:

var resultsWithPositiveBalance = xml.Descendants("Invoice")
         .Where(x => (!x.Element("balance").ToDecimal() ?? 0 ) > 0);
0 голосов
/ 21 февраля 2019

Просто сделайте сравнение в соответствии с TryParse.Вы можете воспользоваться функцией C # 7, позволяющей объявлять значение в строке.

Например:

var resultsWithPositiveBalance = xml.Descendants("Invoice")
.Where(x => !x.Element("balance").IsEmpty);
.Where(x => Decimal.TryParse(x.Element("balance").Value, out var val) && val > 0)

Так как TryParse будет обрабатывать, если элемент для вас уже пуст,Вы также можете отказаться от проверки этого.В итоге вы можете получить желаемый результат с помощью:

var resultsWithPositiveBalance = xml.Descendants("Invoice")
.Where(x => decimal.TryParse(x.Element("balance").Value, out var val) && val > 0);
...