38 votes

Pourquoi C # ne me permet-il pas d'appeler une méthode void dans le cadre de l'instruction return?

Je suis curieux de savoir s'il existe une raison légitime pour laquelle C # ne prend pas en charge l'appel d'une méthode void dans le cadre de l'instruction return lorsque le type de résultat de la méthode appelante est également annulé.

 public void MethodA() 
{ 
    return; 
}

public void MethodB() 
{
    return MethodA();
}
 

Nous verrions donc normalement ceci:

 public void MethodMeh() 
{
    if (expression) 
    {
        MethodA();
        return;
    }

    // Do more stuff
}
 

... quand nous pourrions utiliser ceci à la place:

 public void MethodAwesome() 
{
    if (expression) 
        return MethodA();

    // Do more stuff
}
 

Est-ce une limitation de la langue en raison de la façon dont C # gère le vide?

39voto

dan04 Points 33306

Parce que c'est tout simplement la façon dont la langue est définie.

Une méthode peut utiliser return des déclarations de revenir à son appelant. Dans une méthode retournant void, return états ne peuvent pas indiquer de l'expression. Dans une méthode retournant non-void, return états doivent inclure une expression qui calcule la valeur de retour.

C'est une décision arbitraire (probablement du fait de la compatibilité avec le C ANSI et ses autres descendants), et d'autres langages de faire les choses différemment.

Par exemple, en Python, toutes les fonctions renvoient une valeur. Si vous exécutez une return déclaration sans valeur, ou de laisser le contrôle à atteindre la fin de la fonction, c'est juste comme vous l'aviez écrit, return None.

En revanche, Pascal limites de la terminologie de l' function pour les sous-programmes qui ont une valeur de retour; si vous ne voulez pas rentrer quoi que ce soit, vous utilisez un procedure à la place.

28voto

minitech Points 87225

void est l'absence d'information; cela n'a aucun sens de le retourner. Ce n'est pas un type *, et ce n'est pas une valeur, contrairement à d'autres langues. Non, ce n'est pas vraiment une limitation.

* En quelque sorte, comme @Lucas le fait remarquer. C'est un type d'information. cela ne représente pas réellement un type au sens habituel. Vous ne pouvez pas en avoir un.

7voto

svick Points 81772

Votre question est un peu de la différence entre le void type et l' unit type (le plus souvent vu dans les langages fonctionnels comme F#).

Fondamentalement, void n'est pas un vrai type. Bien qu'il y est System.Void pour la réflexion, vous ne pouvez pas utiliser void dans la plupart des endroits où vous pouvez utiliser un type réel: vous ne pouvez pas avoir une variable de type void et vous ne pouvez pas l'utiliser dans les génériques (même si la possibilité d'écrire Func<void> serait parfois très utile).

D'autre part, unit en F# est un type réel: elle a une (unique) valeur (appelés ()), vous pouvez écrire l'équivalent de Func<void> (écrit unit -> unit, où la première unit signifie "pas de paramètres", similaire à l'écriture d' void dans la liste des paramètres en C) et vous pouvez avoir des variables de type unit. Par exemple:

let unitTest (f : unit -> unit) =
    let nothing : unit = f()
    ()

La dernière ligne montre effectivement qu'en F#, parfois, vous devez renvoyer explicitement unit.

4voto

codenheim Points 6836

Il descend par un choix de la langue designer.

À partir d'un type de point de vue, nulle n'a pas d'énumération de valeurs, de sorte qu'il n'est pas judicieux de renvoyer une valeur "nulle" type? le vide est l'absence de type ou de contexte d'évaluation.

Vous ne peut pas instancier ou de retour "vide" en C# ou Java.

Si vous pouviez le faire, vous devez également être en mesure de dire:

 void i;
 i = (what would go here?)
 return i;

Le ci-dessus ne fait aucun sens, mais il est équivalent à ce que vous proposez.

En fin de compte, en proposant que l'on pourrait se propager de retour void contexte avec l'instruction return est simplement une question de syntaxe de sucre, ce qui revient à choix faits par le concepteur.

Le langage C# spec http://msdn.microsoft.com/en-us/library/aa691305(v=vs. 71).aspx (section 7.1) dit

Rien. Cela se produit lorsque l'expression est une invocation d'une méthode avec un type de retour void. Une expression classés comme rien n'est valide que dans le contexte d'un énoncé-expression (Section 8.6).

A l'inverse, le C++ concepteur de réellement choisi de donner juste le construire vous proposer, mais c'était précisément pour syntaxiques de l'uniformité dans les modèles. En C++, le type de retour d'une fonction de modèle peut être un paramètre du modèle. (Stroustrop Langage de Programmation C++ p 148) Sans elle, il y aurait des cas fréquents de dresser pour tous les types, mais pas pour les nuls, tels que les appels de fonctions imbriquées de type T. Pour cette raison, le texte suivant est valide en C++:

void B() {
  return;
}

void A() {
  return B(); // legal C++ - doesn't yield a value
}

// But even in C++ the next line is illegal
int i = A();

Si la déclaration de l'expression "retour B();" où B est une fonction void n'est qu'un raccourci pour "B(); return;" et n'est pas réellement donner une valeur, car il n'y a pas une telle chose comme un vide, une valeur.

4voto

AlexD Points 7089

Ceci n'est pas autorisé selon la spécification de langue. À partir de 15.9.4 de l'ECMA-334 (souligné par moi):

Une instruction return avec une expression ne peut être utilisée que dans un membre de la fonction qui calcule une valeur, c'est-à-dire une méthode avec un type de retour non nul , l'accesseur get d'une propriété ou d'un indexeur ou un opérateur défini par l'utilisateur.

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