2009-02-08 2 views
3

Я построение XML десериализации для проекта, и я перебежать этот тип кода ситуации довольно часто:C# ?? в сочетании с: вопросом

var myVariable = ParseNDecimal(xml.Element("myElement")) == null ? 
       0 : ParseNDecimal(xml.Element("myElement")).Value; 

Есть ли лучший способ, чтобы написать это заявление?

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

+0

«условный», а не «тернарный» оператор –

+0

Это утверждение слишком длинное. Независимо от того, какой синтаксис вы выберете, вы должны разделить его. –

ответ

6

Вы можете использовать метод расширения:

public static T TryGetValue<T>(this XmlElement element) { 
    if (null == element) return default(T); 
    return (T)element.Value; 
} 
... 
... 
var myVariable = xml.Element("myElement").TryGetValue<decimal>(); 

EDIT:

"универсальной" решение:

static class Program { 
    static void Main() { 
     var xmlDecimal = new XElement("decimal"); 
     xmlDecimal.Value = (123.456m).ToString(); 
     decimal valueOfDecimal_1 = xmlDecimal.ValueAs<decimal>(decimal.TryParse); 
     bool valueOfBool_1 = xmlDecimal.ValueAs<bool>(bool.TryParse); 

     var xmlBool = new XElement("bool"); 
     xmlBool.Value = true.ToString(); 
     decimal valueOfDecimal_2 = xmlBool.ValueAs<decimal>(decimal.TryParse); 
     bool valueOfBool_2 = xmlBool.ValueAs<bool>(bool.TryParse); 
    } 
} 

public static class StaticClass { 
    public delegate bool TryParseDelegate<T>(string text, out T value); 
    public static T ValueAs<T>(this XElement element, TryParseDelegate<T> parseDelegate) { 
     return ValueAs<T>(element, parseDelegate, default(T)); 
    } 
    public static T ValueAs<T>(this XElement element, TryParseDelegate<T> parseDelegate, T defaultValue) { 
     if (null == element) { return defaultValue; } 

     T result; 
     bool ok = parseDelegate(element.Value, out result); 
     if (ok) { return result; } 

     return defaultValue; 
    } 
} 
+0

+1 Хороший, избили меня. – AnthonyWJones

+1

Хотя я бы назвал другое имя, например GetValueOrDefault. У TryXXXX есть ожидание возврата bool и выбор параметра out. – AnthonyWJones

+0

Я сомневаюсь, что это может быть общим в реальном коде, который, как я подозреваю, использует XAttribute, а не XElement.Value. Как может работать от строки до десятичной? –

5

Edit: Учитывая отредактированный вопрос, это много проще.

Опять же он использует метод расширения, но теперь нет необходимости делать преобразование в методе.

var myVariable = ParseNDecimal(xml.Element("myElement").ValueOrDefault("0")); 

... 

public static string ValueOrDefault(this XElement element, 
            string defaultValue) 
{ 
    return element != null ? element.Value : defaultValue; 
} 

Если вам не нравится метод, принимая строковый параметр, вы можете сделать это взять object и вызвать ToString, а затем вызвать его так:

var myVariable = ParseNDecimal(xml.Element("myElement").ValueOrDefault(0m)); 

однако, что чувствует себя немного неправильно для меня. Он предполагает, что синтаксический анализ будет обратным форматом ToString.

Оригинальный ответ

Там нет ничего особенно на языке, чтобы помочь вам. (Я не уверен, что у вас есть точный код право - вы не значит, что-то с XAttribute?) Я предлагаю писать служебный метод:

var myVariable = xml.Element("myElement").ValueOrDefault(0m); 

... 

public static decimal ValueOrDefault(this XElement element, 
            decimal defaultValue) 
{ 
    return element != null ?(decimal) element.Value : defaultValue; 
} 

Если изменить код в вопрос, я сделаю аналогично для кода здесь. Я подозреваю, что вы сделал означает использовать XAttribute, что приводит к проблеме с дженериками - я не написал выше в общих чертах, потому что я считаю, что вы захотите позвонить оператору «преобразование в десятичный» . Общий прилив не будет делать этого, поскольку он не знает, какое преобразование вы хотите во время компиляции. Вы можете, однако, перегрузить вышеуказанный метод для всех интересующих вас типов результатов.

+0

@Jon: Вы имели в виду (element! = Null)? –

1

Вы можете использовать? оператор, чтобы написать это немного более чисто, но я не уверен, что вы должны ...

Element() возвращает null из не существует дочернего элемента с этим именем, так что вы можете использовать? для перемещения по элементу по умолчанию. Вы должны сделать это до призывания (decimal) гипса:

var myVariable 
    = (decimal)(xml.Element("myElement") ?? new XElement("myElement", 0)); 

Как я уже говорил, хотя, в то время как это будет работать, я не уверен, что вы должны сделать это. YMMV.

Смежные вопросы