2008-09-16 8 views
47
EmployeeNumber = 
string.IsNullOrEmpty(employeeNumberTextBox.Text) 
    ? null 
    : Convert.ToInt32(employeeNumberTextBox.Text), 

Je me surprends souvent à vouloir faire des choses comme ça (EmployeeNumber est un Nullable<int> car il est une propriété sur un LINQ to SQL DBML objet où la colonne autorise les valeurs NULL). Malheureusement, le compilateur estime qu '"il n'y a pas de conversion implicite entre" null "et" int ", même si les deux types sont valides dans une opération d'assignation à un int nullable par eux-mêmes.Affectation d'opérateur conditionnelle avec types <value> Nullable?

Opérateur de coalescing Null n'est pas une option autant que je peux voir en raison de la conversion inline qui doit arriver sur la chaîne .Text si elle n'est pas nulle. Pour autant que je sache, la seule façon d'y parvenir est d'utiliser une instruction if et/ou de l'assigner en deux étapes. Dans ce cas particulier, je trouve cela très frustrant parce que je voulais utiliser la syntaxe d'initialisation d'objet et cette affectation serait dans le bloc d'initialisation ...

Quelqu'un connaît une solution plus élégante?

+1

Vérifiez l'article de blog connexe d'Eric Lippert: [Type inference woes, part one] (http://blogs.msdn.com/ericlippert/archive/2006/05/24/type-inference-woes-part -one.aspx) – CodesInChaos

+0

[erreur de compilation ** CS0173 **] (http://msdn.microsoft.com/en-us/library/vstudio/hb47kt2f%28v=vs.120%29.aspx) m'a amené ici. – DavidRR

Répondre

60

Le problème se produit parce que l'opérateur conditionnel ne regarde pas comment la valeur est utilisée (attribué dans ce cas) pour déterminer le type de l'expression - - Juste les vraies/fausses valeurs. Dans ce cas, vous avez un null et un Int32 et le type ne peut pas être déterminé (il y a des raisons réelles, il ne peut pas simplement supposer que Nullable <Int32>).

Si vous voulez vraiment l'utiliser de cette manière, vous devez jeter l'une des valeurs à Nullable <Int32> vous, donc C# peut résoudre le type:

EmployeeNumber = 
    string.IsNullOrEmpty(employeeNumberTextBox.Text) 
    ? (int?)null 
    : Convert.ToInt32(employeeNumberTextBox.Text), 

ou

EmployeeNumber = 
    string.IsNullOrEmpty(employeeNumberTextBox.Text) 
    ? null 
    : (int?)Convert.ToInt32(employeeNumberTextBox.Text), 
+4

Vous pouvez également écrire 'new int?()'. – SLaks

+6

Vous dites qu'il y a de vraies raisons qu'il ne peut pas assumer Nullable . Quelles raisons? – BlueMonkMN

+1

@SLaks Ou 'default (int?)'. – IllidanS4

3

Vous pouvez lancer la sortie Convertir:

EmployeeNumber = string.IsNullOrEmpty(employeeNumberTextBox.Text) 
    ? null 
    : (int?)Convert.ToInt32(employeeNumberTextBox.Text) 
8

Je pense qu'une méthode utilitaire pourrait aider à rendre ce nettoyeur.

public static class Convert 
{ 
    public static T? To<T>(string value, Converter<string, T> converter) where T: struct 
    { 
     return string.IsNullOrEmpty(value) ? null : (T?)converter(value); 
    } 
} 

puis

EmployeeNumber = Convert.To<int>(employeeNumberTextBox.Text, Int32.Parse); 
+0

C'est une très bonne idée, et un exemple où les méthodes génériques et d'extension sont extrêmement géniales :) – Grank

6

Alors que Alex fournit la réponse correcte et proximale à votre question, je préfère utiliser TryParse:

int value; 
int? EmployeeNumber = int.TryParse(employeeNumberTextBox.Text, out value) 
    ? (int?)value 
    : null; 

Il est plus sûr et prend en charge des cas d'entrée non valide ainsi que votre scénario de chaîne vide. Sinon, si l'utilisateur entre quelque chose comme 1b, ils seront présentés avec une page d'erreur avec l'exception non gérée provoquée par Convert.ToInt32(string).

+0

Je préfère valider l'entrée de l'utilisateur en utilisant l'ASP.NET CompareValidator, qui peut être réglé sur un opérateur de DataTypeCheck et un type d'int . Cela garantit que l'entrée ne sera jamais autre chose qu'un entier, et le fait côté client si c'est possible. – Grank

1
//Some operation to populate Posid.I am not interested in zero or null 
int? Posid = SvcClient.GetHolidayCount(xDateFrom.Value.Date,xDateTo.Value.Date).Response; 
var x1 = (Posid.HasValue && Posid.Value > 0) ? (int?)Posid.Value : null; 

EDIT: Brève explication ci-dessus, je tentais d'obtenir la valeur de Posid (si sa non nulle int et ayant une valeur supérieure à 0) dans varibale X1. J'ai dû utiliser (int?) sur Posid.Value pour obtenir l'opérateur conditionnel ne jetant aucune erreur de compilation. Juste un FYI GetHolidayCount est une méthode WCF qui pourrait donner null ou n'importe quel nombre. Espérons que ça aide

+0

Il est généralement recommandé d'inclure une description de ce que fait votre code au lieu de simplement afficher le code. Cela aide la personne posant la question (et les personnes qui ont trouvé cette question tout en éprouvant le même problème) à comprendre ce que fait votre solution. –

+0

Merci Robert de l'avoir signalé. – Sandeep

Questions connexes