139 votes

Pourquoi n ' t c# appuyer le retour des références ?

J’ai lu que .NET prend en charge le retour des références, mais c# ne fonctionne pas. Y a-t-il une raison particulière ? Pourquoi je ne peux pas faire quelque chose comme :

187voto

Eric Lippert Points 300275

Mise à JOUR: Cette question a été l'objet de mon blog sur 23 juin 2011. Merci pour la grande question!


Vous avez raison; .NET prend en charge les méthodes qui retournent géré références à des variables. .NET prend également en charge les variables locales qui contiennent géré des références à d'autres variables. (Notez cependant que .NET ne prend pas en charge les champs ou les tableaux qui contiennent géré des références à d'autres variables, parce que trop complique la collecte des ordures histoire. Aussi le "géré de référence pour la variable" types de sont pas convertibles en un objet, et donc ne peuvent pas être utilisés comme arguments de type pour les types génériques ou des méthodes.)

Intervenant "RPM1984" pour une raison quelconque demandé une citation pour ce fait. RPM1984 je vous encourage à lire la CLI de spécification de la Partition j'ai l'Article 8.2.1.1, "Gérer les pointeurs et types" pour plus d'informations sur cette fonctionnalité .NET.

Il est tout à fait possible de créer une version de C# qui prend en charge ces deux caractéristiques. Vous pouvez faire des choses comme

static ref int Max(ref int x, ref int y) 
{ 
  if (x > y) 
    return ref x; 
  else 
    return ref y; 
} 

et puis l'appeler avec

int a = 123;
int b = 456; 
ref int c = ref Max(ref a, ref b); 
c += 100;
Console.WriteLine(b); // 556!

Je sais empiriquement qu'il est possible de créer une version de C# qui prend en charge ces fonctions parce que j'ai fait. Des programmeurs avancés, en particulier les personnes de portage C++ code, souvent nous demander pour plus de C++comme la capacité à faire des choses avec des références sans avoir à sortir le gros marteau de l'utilisation de pointeurs et les épingler la mémoire de tous sur la place. En utilisant géré les références que vous obtenir ces avantages sans payer le coût de vissage vos de collecte des ordures de la performance.

Nous avons considéré cette fonctionnalité, et effectivement mis en oeuvre assez pour montrer aux autres équipes internes afin d'obtenir leurs commentaires. Toutefois, à ce moment de nos recherches , nous croyons que la fonctionnalité n'a pas assez large appel ou de contraindre l'utilisation de cas pour en faire une véritable langue prise en charge de la fonctionnalité. Nous avons d'autres priorités, et une quantité limitée de temps et d'efforts, donc nous n'allons pas faire cette fonctionnalité n'importe quand bientôt.

Aussi, le faire de manière appropriée serait d'exiger des changements à la CLR. Droit maintenant, le CLR traite ref-retour des méthodes juridiques , mais invérifiable, car nous n'avons pas un détecteur qui détecte cette situation:

ref int M1(ref int x)
{
    return ref x;
}

ref int M2()
{
    int y = 123;
    return ref M1(ref y); // Trouble!
}

int M3()
{
    ref int z = ref M2();
    return z;
}

M3 retourne le contenu de M2 de variable locale, mais la durée de vie de cette variable est terminé! Il est possible d'écrire un détecteur qui détermine les usages de ref-retours qui de toute évidence ne pas violer la pile de la sécurité. Ce que nous aimerions faire est d'écrire un tel détecteur, et si le détecteur ne pouvait pas prouver pile à la sécurité, alors nous ne permettrait pas l'utilisation de réf retourne dans cette partie du programme. Ce n'est pas une énorme quantité de dev de travail à faire, mais c'est beaucoup de travail supplémentaire pour les équipes chargées des contrôles pour s'assurer que nous avons tous les cas. C'est juste une autre chose qui augmente le coût de la fonction au point où maintenant les avantages ne l'emportent pas sur les coûts.

Si vous pouvez vous le décrivez-moi pourquoi vous voulez cette fonction, j'apprécierais vraiment que. Le plus d'informations que nous avons de vrais clients au sujet de pourquoi ils le veulent, plus il a de chance de le faire dans le produit un jour. C'est une mignonne petite fonctionnalité et j'aimerais être en mesure de l'obtenir pour les clients en quelque sorte, si l'intérêt est suffisant.

(Voir aussi les questions Est-il Possible de Retourner une Référence à une Variable en C#? et puis-je utiliser une référence à l'intérieur d'un C# fonction comme le C++?)

21voto

Rick Sladkey Points 23389

Vous parlez des méthodes qui renvoient une référence à un type de valeur. La seule intégré dans l'exemple en C# que je connaisse est la matrice-accesseur d'un type de valeur:

public struct Point
{
    public int X { get; set; }
    public int Y { get; set; }
}

et maintenant créer un tableau de cette structure:

var points = new Point[10];
points[0].X = 1;
points[0].Y = 2;

Dans ce cas - points[0], le tableau de l'indexeur, est de retour d'une référence à la structure. Il est impossible d'écrire votre propre indexeur (par exemple pour une collection personnalisée), qui a cette même "renvoyer une référence" de comportement.

Je n'ai pas de conception du langage C# donc je ne sais pas tout le raisonnement derrière n'est pas soutenu, mais je pense que la réponse pourrait être: nous pouvons très bien sans elle.

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