Pregunta

Estoy construyendo un XML deserializador para un proyecto y me encuentro con este tipo de situaciones código con bastante frecuencia:

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

¿Hay una mejor manera de escribir esta declaración?

EDIT:. Tal vez debería haber aclarado mi ejemplo, como yo tengo un método de ayuda para analizar la cadena en un número decimal

¿Fue útil?

Solución

Puede utilizar el método de extensión:

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:

La solución "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;
    }
}

Otros consejos

Editar:. Teniendo en cuenta la cuestión editado, esto es mucho más simple

Una vez más, utiliza un método de extensión, pero ahora no hay necesidad de hacer una conversión en el 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;
}

Si no te gusta el método de tomar un parámetro de cadena, que podría hacer que tome object y llamar ToString, a continuación, llamar de esta manera:

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

Sin embargo, se siente un poco mal a mí. Se supone que el análisis será el inverso del formato ToString.

Respuesta original

No hay nada especial en el idioma que le ayude. (No estoy seguro de que usted tiene el código correcto exacta - no quiere decir algo con un XAttribute?) Te sugiero escribir un método de utilidad:

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

...

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

Si se ajusta el código en la pregunta, voy a hacer lo mismo para el código aquí. Sospecho que hicieron significa utilizar XAttribute, lo que conduce a un problema con los genéricos - No he escrito lo anterior de una manera genérica, porque creo que tendrá que llamar a la XAttribute "conversión a decimal "operador. Un molde genérico no hacerlo, ya que no sabe qué tipo de conversión que desea en tiempo de compilación. Puede, sin embargo, sobrecargar el método anterior para todos los tipos de resultados que le interesan.

Puede utilizar el ?? operador para escribir esto un poco más limpia, pero no estoy seguro de que usted debe ...

Element() vuelve nula de que no hay elemento hijo con ese nombre, así que de ahí se puede usar ?? para deslizar en un elemento de forma predeterminada. Es necesario hacer esto antes de la invocación del elenco (decimal):

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

Como he dicho, sin embargo, mientras que esto va a funcionar, no estoy seguro de que debe hacer esto. Tu caso es distinto.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top