Question

Je construis un XML désérialiseur pour un projet et je courir à travers ce type de situation de code assez souvent:

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

Y at-il une meilleure façon d'écrire cette déclaration?

EDIT:. Peut-être que je aurais dû préciser mon exemple que j'ai une méthode d'aide pour analyser la chaîne en nombre décimal

Était-ce utile?

La solution

Vous pouvez utiliser la méthode d'extension:

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 solution "universelle":

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

Autres conseils

Edit:. Compte tenu de la question éditée, ce qui est beaucoup plus simple

Encore une fois, il utilise une méthode d'extension, mais maintenant il n'y a pas besoin de faire une conversion dans la méthode.

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

...

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

Si vous ne souhaitez pas la méthode prenant un paramètre de chaîne, vous pouvez le faire prendre object et appeler ToString, puis appelez comme ceci:

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

Cependant, cela se sent un peu mal pour moi. Il suppose que l'analyse sera l'inverse de la mise en forme ToString.

Réponse originale

Il n'y a rien en particulier dans la langue pour vous aider. (Je ne suis pas sûr que vous avez le code exact droit - voulez-vous dire pas quelque chose avec un XAttribute?) Je vous suggère d'écrire une méthode utilitaire:

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

...

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

Si vous réglez le code dans la question, je ferai de même pour le code ici. Je suppose que vous ne signifie utiliser XAttribute, ce qui conduit à un problème avec les génériques - je ne l'ai pas écrit ce qui précède d'une manière générique, parce que je crois que vous voulez appeler la XAttribute « conversion en décimal "opérateur. Un casting générique ne le fera pas, car il ne sait pas quel genre de conversion que vous voulez au moment de la compilation. Vous pouvez toutefois surcharger la méthode ci-dessus pour tous les types de résultats qui vous intéressent.

Vous pouvez utiliser le ?? opérateur d'écrire cela un peu plus propre, mais je ne suis pas sûr que vous devriez ...

Element() retourne nulle il n'y a aucun élément enfant avec ce nom, de sorte que c'est là, vous pouvez utiliser ?? pour coulisser dans un élément par défaut. Vous devez le faire avant l'invocation de la distribution de (decimal):

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

Comme je l'ai dit que, alors que cela fonctionnera, je ne suis pas sûr que vous devraient faire. YMMV.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top