36 votes

Pourquoi le compilateur C# n'empêche-t-il pas les propriétés de se référer à elles-mêmes ?

Si je fais cela, j'obtiens un System.StackOverflowException :

private string abc = "";
public string Abc
{
    get
    { 
        return Abc; // Note the mistaken capitalization
    }
}

Je comprends pourquoi : la propriété se réfère à elle-même, ce qui conduit à une boucle infinie. (Voir les questions précédentes aquí y aquí ).

Ce que je me demande (et ce à quoi je n'ai pas vu de réponse dans ces questions précédentes), c'est pourquoi le compilateur C# ne repère pas cette erreur ? Il vérifie d'autres types de références circulaires (classes héritant d'elles-mêmes, etc.), n'est-ce pas ? Est-ce que cette erreur n'est pas assez courante pour être vérifiée ? Ou bien existe-t-il une situation à laquelle je ne pense pas, dans laquelle vous voudriez qu'une propriété se référence elle-même de cette manière ?

46voto

Brandon Points 35624

Vous pouvez voir la raison "officielle" dans le dernier commentaire. aquí .

Posté par Microsoft le 14/11/2008 à 19:52

Merci pour la suggestion de Visual Studio !

Vous avez raison de dire que nous pourrions facilement détecter la récursivité des propriétés, mais nous ne pouvons pas garantir qu'il n'y a rien utile n'est accompli par la récursion. Le corps de la propriété pourrait définir d'autres champs sur votre objet qui changent le comportement de la prochaine récursion, pourrait changer son comportement basé sur les entrées de l'utilisateur depuis la console, ou pourrait même se comporter différemment en fonction sur la base de valeurs aléatoires. Dans ces cas, une propriété auto-récursive pourrait en effet mettre fin à la récursivité, mais nous n'avons aucun moyen de déterminer si c'est le cas au moment de la compilation (sans résoudre le problème d'arrêt !).

Pour les raisons évoquées ci-dessus (et le changement de rupture qu'il faudrait pour l'interdire), nous ne serions pas en mesure de interdire les propriétés auto-récurrentes.

Alex Turner

Responsable de programme

Compilateur Visual C#

14voto

Eric Lippert Points 300275

Un autre point en plus de l'explication d'Alex est que nous essayons de donner des avertissements pour le code qui fait quelque chose que vous n'aviez probablement pas l'intention de faire, de sorte que vous pourriez accidentellement livrer avec le bug .

Dans ce cas particulier, combien de temps l'avertissement vous ferait-il réellement gagner ? Un seul test. Vous découvrirez ce bogue au moment où vous testerez le code, car il se plante toujours immédiatement et meurt de façon horrible. L'avertissement ne vous apporterait pas grand-chose dans ce cas. La probabilité qu'il y ait un subtile dans une évaluation récursive des propriétés est faible.

En revanche, nous hacer donner un avertissement si vous faites quelque chose comme ça :

int customerId; 
...
this.customerId= this.customerId;

Il n'y a pas d'accident horrible, et le code est valide ; il affecte une valeur à un champ. Mais comme il s'agit d'un code absurde, vous n'aviez probablement pas l'intention de le faire. Puisqu'il ne va pas mourir horriblement, nous donnons un avertissement qu'il y a quelque chose ici que vous n'aviez probablement pas l'intention de faire et que vous ne pourriez pas découvrir autrement par un crash.

10voto

dbkk Points 5305

Une propriété se référant à elle-même ne conduit pas toujours à une récursion infinie et à un débordement de pile. Par exemple, ceci fonctionne bien :

int count = 0;
public string Abc
{
    count++;
    if (count < 1) return Abc;
    return "Foo";
}

L'exemple ci-dessus est un exemple factice, mais je suis sûr que l'on pourrait trouver un code récursif utile qui soit similaire. Le compilateur ne peut pas déterminer si une récursion infinie va se produire (problème de l'arrêt).

La génération d'un avertissement dans le cas simple serait utile.

1voto

Max Galkin Points 10116

Ils ont probablement considéré que cela compliquerait inutilement le compilateur sans aucun gain réel.

Vous découvrirez facilement cette coquille la première fois que vous appellerez cette propriété.

1voto

Vlad Points 23480

Tout d'abord, vous recevrez un avertissement pour la variable inutilisée abc .

Deuxièmement, il n'y a rien de mauvais dans la récursion, à condition que ce ne soit pas une récursion sans fin. Par exemple, le code peut ajuster certaines variables internes et ensuite appeler le même getter récursivement. Il n'y a cependant pas de moyen facile pour le compilateur de prouver qu'une récursion est sans fin ou non (la tâche est au moins NP). Le compilateur pourrait attraper certains cas faciles, mais les consommateurs seraient alors surpris que les cas plus compliqués passent à travers les contrôles du compilateur.

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