2009-09-01 8 views
1

Je travaille sur une méthode qui acceptera un StreamWriter, soit une chaîne ou une valeur Nullable, et une longueur, et écrira la valeur à StreamWriter, rembourré à la longueur. Si la valeur est null, je veux écrire des espaces. Je veux faire quelque chose comme l'exemple simplifié suivant, qui est juste à des fins de démonstration.Puis-je créer une fonction générique qui accepte un Nullable <something>?

public void FixedWrite(StreamWriter writer, string value, 
     int length) { 
    if (value == null) value = ""; 
    value = value.PadRight(length); 
    writer.Write(value); 
} 

public void FixedWrite<T>(StreamWriter writer, T value, 
     int length) where T : Nullable /* won't work of course */ { 
    string strVal; 
    if (!value.HasValue) strVal = null; 
    else strVal = value.Value.ToString(); 
    FixedWrite(writer, strVal, length); 
} 

je pouvais avoir pour tous les surcharges différents types sous-jacents (ils sont toutes les dates, ints, bools et décimaux), mais je voulais voir si je pouvais obtenir la version générique de travail. Existe-t-il un moyen de faire en sorte que T soit toujours un type Nullable <> et d'accéder aux propriétés Nullable <> (HasValue et Value)? Ou devrais-je simplement m'en tenir aux surcharges spécifiques au type sous-jacent?

This question pose un problème similaire, mais dans mon cas, les valeurs sont déjà nulles et je veux juste écrire la valeur si elle en a un et les espaces si ce n'est pas le cas.

Répondre

12

Essayez quelque chose comme ceci:

public void FixedWrite<T>(StreamWriter writer, Nullable<T> value, int length) 
    where T : struct 
{ 
    string strVal; 
    if (!value.HasValue) strVal = null; 
    else strVal = value.HasValue.ToString(); 
    FixedWrite(writer, strVal, length); 
} 
+0

Bien sûr. Je rendais cela plus difficile que nécessaire. Merci. –

+0

Cela fonctionne, mais vous * pouvez * passer un paramètre nullable à la méthode générique. –

0

La réponse est non.

Même s'il s'agit d'une structure, elle a été spécifiquement refusée dans le CLR en raison de problèmes de récursivité qui pourraient survenir.

Nullable<Nullable<Nullable<etc.>>>() 
+0

Il est possible de faire ce qu'il veut faire qui est de passer un type nullable comme un paramètre générique. Il est également possible de tester ce type pour null car Nullable n'est plus un type de valeur, il suffit de tester == null –

+0

+1 pour obtenir des informations utiles. Il est possible de passer un nullable comme un paramètre générique, comme le souligne Oplapanax, mais Jaimal a raison, vous ne pouvez pas définir une méthode générique pour restreindre spécifiquement à nullables, ce que je recherchais. Je ne sais pas pourquoi cela a été rejeté, parce que c'est une réponse utile et techniquement correcte à ma question. –

+0

Il n'y a rien de mal conceptuellement avec un 'Nullable >'. Quelque chose comme un 'Dictionary >' pourrait vouloir offrir une méthode 'TryGetvalue' dont la valeur de retour contient le résultat avec une indication de succès. S'il n'y avait pas les restrictions et les comportements excentriques de 'Nullable ', un type logique pour une telle méthode serait un 'Nullable >'. Si la valeur de 'Hasvalue' est vraie, cette' Value' maintient l'élément stocké dans la collection avec la clé spécifiée (si 'Value.HasValue' est faux, cela signifierait que c'est ce qui était stocké dans la collection). – supercat

3
public void FixedWrite<T>(StreamWriter writer, Nullable<T> value, int length) 

mal à cela?

+3

Pour que ceci compile, vous devez contraindre 'T' comme type de valeur, veuillez voir ma réponse. –

+0

Merci. J'étais trop paresseux pour lancer VS pour savoir ce que le compilateur dit réellement :). –

1

Pas besoin de tester HasValue, puisque Nullable est un struct, vous pouvez imposer la « nouvelle() » contrainte « ? »

public void FixedWrite<T>(StreamWriter writer, T value, int length) where T : new() 
{ 
    // just test for NULL 
    string strVal = (value==null) ? string.Empty: value.ToString(); 
    FixedWrite(writer, strVal, length); 
} 

Maintenant, vous l'appelez comme si (en utilisant la notation est la touche):

FixedValue<System.DateTime?>(....) 
+0

Mais je ne serai pas en mesure d'accéder aux méthodes de valeur HasValue et Value car le compilateur ne saura pas qu'il est nullable, non? –

+0

correct; tester NULL signifie qu'il n'a aucune valeur. Si ce n'est pas nul, il a une valeur. –

+0

désolé, édité le code pour supprimer cette déclaration, l'a fait plus clair, espérons. –

Questions connexes