2009-07-01 7 views
0

Je suis nouveau au type de varicelle C# 3.0. Ici, j'ai une question à propos de ce type. Prenez les codes simples suivants dans une bibliothèque comme exemple:Question sur le type de var

public class MyClass { 
    public var Fn(var inValue) 
    { 
     if (inValue < 0) 
     { 
      return 1.0; 
     } 
     else 
     { 
      return inValue; 
     } 
    } 
} 

Je pense que le paramètre est un type anonyme. Si je passe une valeur flottante, alors le Fn devrait retourner un type float. Si un type de double valeur est passé, le Fn retournera-t-il un double type? Que diriez-vous d'un type de valeur entier comme valeur d'entrée?

En fait, je voudrais utiliser le type var avec cette fonction/méthode pour obtenir différents types de retour avec différents types d'entrée dynamiquement. Je ne suis pas sûr si cet usage est correct ou non?

+0

Mes codes peuvent être erronés. J'ai lu quelques articles sur l'utilisation de var dans la portée locale, mais pas dans la bibliothèque comme type var pour les méthodes publiques. Pas sûr puisque je n'ai pas de VS pour le vérifier. –

Répondre

8

Vous ne pouvez pas utiliser var pour les valeurs de retour ou les types de paramètres (ou les champs). Vous pouvez seulement l'utiliser pour les variables locales.

Eric Lippert a un blog post about why you can't use it for fields. Je ne suis pas sûr s'il y en a un similaire pour les valeurs de retour et les types de paramètres. Les types de paramètres n'ont certainement pas beaucoup de sens - d'où le compilateur pourrait-il déduire le type? Juste quelles méthodes vous essayez d'appeler sur les paramètres? (En fait, c'est à peu près ce que F # fait, mais C# est plus conservateur.)

Ne pas oublier que var est strictement typage statique - il est juste un moyen d'obtenir le compilateur de déduire le type statique pour vous. C'est toujours juste un seul type, exactement comme si vous aviez tapé le nom dans le code. (Sauf bien sûr avec des types anonymes vous ne pouvez pas faire, ce qui est une motivation pour la fonction.)

EDIT: Pour plus de détails sur var, vous pouvez télécharger le chapitre 8 de C# en profondeur gratuitement à Manning's site - Ceci inclut la section sur var. Évidemment, j'espère que vous voudrez ensuite acheter le livre, mais il n'y a pas de pression :)

EDIT: Pour répondre à votre objectif réel, vous pouvez mettre en œuvre presque tout cela avec une méthode générique:

public class MyClass 
{ 
    public T Fn<T>(T inValue) where T : struct 
    { 
     Comparer<T> comparer = Comparer<T>.Default; 
     T zero = default(T); 
     if (comparer.Compare(inValue, zero) < 0) 
     { 
      // This is the tricky bit. 
      return 1.0; 
     } 
     else 
     { 
      return inValue; 
     } 
    } 
} 

Comme indiqué dans la liste, le bit délicat est de savoir ce que "1" signifie pour un type arbitraire. Vous pouvez coder en dur un ensemble de valeurs, mais c'est un peu moche:

public class MyClass 
{ 
    private static readonly Dictionary<Type, object> OneValues 
     = new Dictionary<Type, object> 
    { 
     { typeof(int), 1 }, 
     { typeof(long), 1L }, 
     { typeof(double), 1.0d }, 
     { typeof(float), 1.0f }, 
     { typeof(decimal), 1m }, 
    }; 

    public static T Fn<T>(T inValue) where T : struct 
    { 
     Comparer<T> comparer = Comparer<T>.Default; 
     T zero = default(T); 
     if (comparer.Compare(inValue, zero) < 0) 
     { 
      object one; 
      if (!OneValues.TryGetValue(typeof(T), out one)) 
      { 
       // Not sure of the best exception to use here 
       throw new ArgumentException 
        ("Unable to find appropriate 'one' value"); 
      } 
      return (T) one; 
     } 
     else 
     { 
      return inValue; 
     } 
    } 
} 

Icky - mais ça va marcher. Ensuite, vous pouvez écrire:

double x = MyClass.Fn(3.5d); 
float y = MyClass.Fn(3.5f); 
int z = MyClass.Fn(2); 

etc

+2

Ha, je t'ai battu deux fois ce soir. Cela n'arrivera pas souvent. Je vais attendre vos modifications supérieures si :) –

+0

Je suis désolé John je vais évaluer le "édition supérieure" mais +1 pour votre humour aussi :) –

5

Vous ne pouvez pas utiliser var comme type de retour pour une méthode.

+0

tant pis, comme je l'ai deviné. Pas comme Ruby ou Python. C'est bon. Merci! –

+1

@David: Ce sont des langages * dynamiques *. Si vous n'aimez pas le typage statique, vous ne vous amuserez pas beaucoup en C#. Bien que C# 4 introduit le typage dynamique, mais je ne l'utiliserais que là où vous en auriez vraiment besoin. C# est construit autour d'être typé statiquement. –

Questions connexes