J'ai lu que .NET prend en charge le retour de références, mais pas C #. Y a-t-il une raison particulière? Pourquoi je ne peux pas faire quelque chose comme:
static ref int Max(ref int x, ref int y)
{
if (x > y)
return ref x;
else
return ref y;
}
c#
.net
reference
return-type
Tom Sarduy
la source
la source
return ref x
C# 7
:)Réponses:
Cette question a fait l'objet de mon blog le 23 juin 2011 . Merci pour la bonne question!
L'équipe C # envisage cela pour C # 7. Voir https://github.com/dotnet/roslyn/issues/5233 pour plus de détails.
MISE À JOUR: La fonctionnalité est arrivée en C # 7!
Vous avez raison; .NET prend en charge les méthodes qui renvoient des références managées à des variables. .NET prend également en charge les variables locales qui contiennent des références managées à d'autres variables. (Notez cependant que .NET ne prend pas en charge les champs ou les tableaux qui contiennent des références gérées à d'autres variables car cela complique excessivement l'histoire du garbage collection. De plus, les types «référence gérée à une variable» ne sont pas convertibles en objet et ne peuvent donc pas être utilisés comme les arguments de type aux types ou méthodes génériques.)
Le commentateur "RPM1984" a pour une raison quelconque demandé une citation pour ce fait. RPM1984 Je vous encourage à lire la spécification CLI Partition I Section 8.2.1.1, «Pointeurs gérés et types associés» pour plus d'informations sur cette fonctionnalité de .NET.
Il est tout à fait possible de créer une version de C # qui prend en charge ces deux fonctionnalités. Vous pourriez alors faire des choses comme
puis appelez-le avec
Je sais empiriquement qu'il est possible de créer une version de C # qui prend en charge ces fonctionnalités parce que je l'ai fait . Les programmeurs avancés, en particulier les personnes qui portent du code C ++ non géré, nous demandent souvent plus de capacité à faire des choses avec des références sans avoir à se débarrasser du gros marteau de l'utilisation de pointeurs et d'épinglage de mémoire partout. En utilisant des références gérées, vous bénéficiez de ces avantages sans payer le coût de la dégradation de vos performances de récupération de place.
Nous avons pris en compte cette fonctionnalité et en avons mis en œuvre suffisamment pour que d'autres équipes internes puissent en bénéficier. Cependant, à l'heure actuelle, sur la base de nos recherches, nous pensons que la fonctionnalité n'a pas un attrait suffisamment large ou des cas d'utilisation convaincants pour en faire une véritable fonctionnalité de langage prise en charge . Nous avons d'autres priorités plus élevées et une quantité limitée de temps et d'efforts disponibles, nous n'allons donc pas faire cette fonctionnalité de si tôt.
En outre, le faire correctement nécessiterait des modifications du CLR. À l'heure actuelle, le CLR traite les méthodes de retour de référence comme légales mais invérifiables car nous n'avons pas de détecteur qui détecte cette situation:
M3 renvoie le contenu de la variable locale de M2, mais la durée de vie de cette variable est terminée! Il est possible d'écrire un détecteur qui détermine les utilisations des retours de référence qui ne violent clairement pas la sécurité de la pile. Ce que nous ferions serait d'écrire un tel détecteur, et si le détecteur ne pouvait pas prouver la sécurité de la pile, nous n'autoriserions pas l'utilisation de retours de référence dans cette partie du programme. Ce n'est pas un travail de développement énorme pour le faire, mais c'est beaucoup de travail pour les équipes de test de s'assurer que nous avons vraiment tous les cas. C'est juste une autre chose qui augmente le coût de la fonctionnalité au point où, pour le moment, les avantages ne l'emportent pas sur les coûts.
Si vous pouvez me décrire pourquoi vous voulez cette fonctionnalité, je l'apprécierais vraiment . Plus nous avons d'informations de la part de vrais clients sur les raisons pour lesquelles ils le souhaitent, plus il est probable que cela deviendra le produit un jour. C'est une jolie petite fonctionnalité et j'aimerais pouvoir la proposer aux clients d'une manière ou d'une autre s'il y a suffisamment d'intérêt.
(Voir aussi les questions connexes Est-il possible de renvoyer une référence à une variable en C #? Et Puis-je utiliser une référence dans une fonction C # comme C ++? )
la source
y
vie après son retourM2
? Je m'attendrais à ce que cette fonctionnalité fonctionne comme des lambdas capturant les habitants. Ou est le comportement que vous avez proposé parce que c'est ainsi que CLR gère ce scénario?Vous parlez de méthodes qui renvoient une référence à un type valeur. Le seul exemple intégré en C # que je connaisse est l'accesseur de tableau d'un type valeur:
et maintenant créez un tableau de cette structure:
Dans ce cas
points[0]
, l' indexeur de tableau renvoie une référence à struct. Il est impossible d'écrire votre propre indexeur (par exemple pour une collection personnalisée), qui a le même comportement «renvoyer une référence».Je n'ai pas conçu le langage C #, donc je ne connais pas tout le raisonnement derrière le fait de ne pas le soutenir, mais je pense que la réponse courte pourrait être: nous pouvons très bien nous en passer.
la source
Vous pouvez toujours faire quelque chose comme:
la source
C # 7.0 prend en charge le renvoi de références. Voir ma réponse ici .
la source