Вопрос

Я создаю десериализатор XML для проекта и довольно часто сталкиваюсь с подобным типом кодовой ситуации:

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

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

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

Это было полезно?

Решение

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

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>();

Редактировать:

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

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

Другие советы

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

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

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, что приводит к проблеме с дженериками - я не написал выше в обобщенном виде, потому что я полагаю, что вы захотите вызвать XAttribute оператор "преобразование в десятичную систему счисления".Универсальное приведение не будет этого делать, так как оно не знает, какой тип преобразования вы хотите во время компиляции.Однако вы можете перегрузить описанный выше метод для всех интересующих вас типов результатов.

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

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

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

Однако, как я уже сказал, хотя это и сработает, я не уверен, что вы следует сделай это.ИММВ.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top