35 votes

Cast objet en décimal? (décimal annulable)

Si vous avez ceci dans le setter d'une propriété:

 decimal? temp = value as decimal?;
 

valeur = "90"

Mais après le casting, temp est nul ...

Quelle est la bonne façon de faire ce casting?

70voto

Konrad Rudolph Points 231505

Unboxing ne fonctionne que si le type est identique! Vous ne pouvez pas unbox un object qui ne contient pas la valeur cible. Ce que vous avez besoin est quelque chose le long des lignes de

decimal tmpvalue;
decimal? result = decimal.TryParse((string)value, out tmpvalue) ?
                  tmpvalue : (decimal?)null;

Ce regarde si la valeur est analysée comme un decimal. Si oui, alors l'attribuer result; autrement affecter null. Le code suivant fait environ le même et peut-être plus facile à comprendre pour les personnes qui ne connaissent pas l'opérateur conditionnel ?::

decimal tmpvalue;
decimal? result = null;
if (decimal.TryParse((string)value, out tmpvalue))
    result = tmpvalue;

6voto

vous devez analyser le système décimal. Mais si vous voulez que votre décimal être null si la chaîne n'est pas correcte, utilisez TryParse :

decimal parsedValue;
decimal? temp = decimal.TryParse(value, out parsedValue)
                ? value
                : (decimal?)null;

De cette façon, vous permettra d'éviter les exceptions lors de l'analyse de mauvais formatage de chaînes de caractères.

Presque tous les types primitifs de fournir une analyse et TryParse des méthodes de conversion de chaîne de caractères.

Est est également recommandé de passer un la culture pour le fournisseur argument à la méthode pour éviter les problèmes avec le séparateur décimal. Si vous êtes en train de lire à partir d'un autre système, CultureInfo.InvariantCulture est probablement la voie à suivre (mais ce n'est pas la valeur par défaut).

bool TryParse(string s, NumberStyles style,
  IFormatProvider provider, out decimal result)

4voto

Stephen Drew Points 524

Si vous ne souhaitez pas analyser les chaînes, mais vous voulez vous assurer que vous recevez, soit null, une virgule ou un nullable décimal, alors vous pourriez faire quelque chose comme ceci:

public static Nullable<T> Convert<T>(object input) 
    where T : struct
{
    if (input == null)
        return null;
    if (input is Nullable<T> || input is T)
        return (Nullable<T>)input;
    throw new InvalidCastException();
}

Vous pouvez le faire retourner la valeur null sur la dernière ligne au lieu si vous souhaitez éviter les exceptions, bien que ce ne serait pas la distinction entre les vraies valeurs null et mauvais jette.

Notez que vous devez utiliser le "est" de l'opérateur, comme le "comme" opérateur de ne pas travailler sur les types de valeur, et de la coulée, sans que la vérification jeté un InvalidCastException.

Vous pouvez également faire une extension de la méthode:

public static class ObjectExtensions
{
    public static Nullable<T> ToNullable<T>(this object input)
        where T : struct
    {
        if (input == null)
            return null;
        if (input is Nullable<T> || input is T)
            return (Nullable<T>)input;
        throw new InvalidCastException();
    }
}

Et de l'utiliser comme ceci:

object value = 123.45m;
decimal? dec = value.ToNullable<decimal>();

Cela permettra d'éviter le contrat de code des avertissements à propos de l'unboxing des références nulles.

3voto

StevenMcD Points 5168

et si vous utilisez décimal? temp = (décimal?) valeur;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X