Pergunta

Estou construindo uma Deserializer XML para um projeto e eu correr em este tipo de situação código com bastante frequência:

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

Existe uma maneira melhor para escrever esta afirmação?

EDIT:. Talvez eu deveria ter esclarecido o meu exemplo, como eu tenho um método auxiliar para analisar a cadeia em um decimal

Foi útil?

Solução

Você pode usar o método de extensão:

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:

A solução "universal":

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

Outras dicas

Editar:. Dada a questão editado, isso é muito mais simples

Novamente ele usa um método de extensão, mas agora não há necessidade de fazer uma conversão no método.

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

...

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

Se você não gosta do método de tomar um parâmetro de cadeia, você poderia fazê-lo tomar object e ToString chamada, em seguida, chamá-lo assim:

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

No entanto, que se sente um pouco errado para mim. Assume-se que a análise será o inverso de ToString formatação.

resposta Original

Não há nada particularmente na língua para ajudá-lo. (Eu não tenho certeza de que você tem o código exato direita - não fazer-lhe algo média com um XAttribute?) Eu sugiro escrever um método utilitário:

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

...

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

Se você ajustar o código em questão, eu vou fazer o mesmo para o código aqui. Eu suspeito que você se média de usar XAttribute, o que leva a um problema com os genéricos - Eu não escrevi o exposto de uma forma genérica, porque eu acredito que você vai querer chamar a conversão XAttribute" para decimal "operador. Um elenco genérico não vai fazer isso, pois não sabe que tipo de conversão que você quer em tempo de compilação. Você pode, no entanto, sobrecarregar o método acima para todos os tipos de resultados que você está interessado.

Você pode usar o ?? operador para escrever este um pouco mais limpa, mas não tenho certeza de que você deveria ...

Element() retorna nula de que não há elemento filho com esse nome, de modo que é onde você poderia usar ?? a deslizar em um elemento padrão. Você precisa fazer isto antes de a invocação do elenco (decimal):

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

Como eu disse, porém, enquanto isso vai funcionar, eu não tenho certeza de que você deve fazer isso. YMMV.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top