Domanda

Sto costruendo un XML Deserializer per un progetto e ho eseguito in questo tipo di situazione di codice abbastanza spesso:

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

C'è un modo migliore di scrivere questa affermazione?

EDIT:. Forse avrebbe dovuto chiarire il mio esempio come io ho un metodo di supporto per analizzare la stringa in un numero decimale

È stato utile?

Soluzione

È possibile utilizzare il metodo di estensione:

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

Modifica

La soluzione "universale":

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

Altri suggerimenti

Modifica:. Data la domanda modificato, questo è molto più semplice

Anche in questo caso utilizza un metodo di estensione, ma ora non c'è bisogno di fare una conversione nel metodo.

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

...

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

Se non ti piace il metodo di prendere un parametro di stringa, si potrebbe rendere prendere object e chiamare ToString, quindi chiamare in questo modo:

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

Tuttavia, che si sente un po 'sbagliato per me. Si presuppone che l'analisi sarà il contrario di formattazione ToString.

risposta originale

Non c'è niente di particolarmente nella lingua di aiutarvi. (Io non sono sicuro che hai il codice esatto destra - non si intende qualcosa con un XAttribute?) Io suggerirei di scrivere un metodo di utilità:

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

...

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

Se si regola il codice in questione, lo farò allo stesso modo per il codice qui. Ho il sospetto che ha significa utilizzare XAttribute, che porta ad un problema con i generici - non ho scritto quanto sopra in modo generico, perché credo che si vuole chiamare il XAttribute "conversione a decimale "operatore. Un cast generica non lo farà, perché non sa che tipo di conversione che si desidera al momento della compilazione. È possibile, tuttavia, sovraccaricare il metodo di cui sopra per tutti i tipi di risultato che ti interessa.

È possibile utilizzare l'?? all'operatore di scrivere questo un po 'più pulito, ma non sono sicuro che si dovrebbe ...

Element() restituisce il valore null di non v'è alcun elemento figlio con quel nome, così che è dove si potrebbe usare ?? a scorrere in un elemento di default. Hai bisogno di fare questo prima di l'invocazione del cast (decimal):

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

Come ho detto, però, mentre questo lavoro, non sono sicuro che si dovrebbe fare questo. YMMV.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top