Passage par valeur signifie qu'une copie d'un argument est passée. Les modifications apportées à cette copie ne changent pas l'original. P>
Passage par référence signifie une référence à l'original est passé. Les modifications apportées à la référence affectent l'original. P>
Ref indique au compilateur que l'objet est initialisé avant d'entrer dans la fonction. Réf signifie que la valeur est déjà définie, la méthode peut donc la lire et la modifier. Ref est de deux manières, à la fois de l'intérieur et de l'extérieur. P>
Out indique au compilateur que l'objet sera supposé dans la fonction. Out signifie que la valeur n'est pas déjà définie et doit donc être définie avant d'appeler le retour. Out n'est qu'un moyen, ce qui est sorti. P>
Donc, dans quels scénarios alloueriez-vous l'utilisation des mots-clés Ref et Out, en passant par référence ou en passant par la valeur? Des exemples aideraient énormément. P>
aide grandement appréciée. p>
7 Réponses :
Vous seriez Vous pouvez bien sûr combiner les paramètres de référence et les paramètres d'une méthode. P> la différence entre mais en plus de l'intention, le compilateur C # piste définitive-assignation et qui fait la différence la plus notable. Il empêche également l'utilisation abusive (lecture) d'un paramètre OUT. P> Réf code> et
out code> sur 1 paramètre. Ils signifient tous les deux «passer par référence».
ref code> et
out code> est principalement dans intention forte>. Ref signale le transport de données à 2 voies, désintègre un passage. P>
void SetOne(out int x)
{
int y = x + 1; // error, 'x' not definitely assigned.
x = 1; // mandatory to assign something
}
void AddTwo(ref int x)
{
x = x + 2; // OK, x is known to be assigned
}
void Main()
{
int foo, bar;
SetOne(out foo); // OK, foo does not have to be assigned
AddTwo(ref foo); // OK, foo assigned by SetOne
AddTwo(ref bar); // error, bar is unassigned
}
Ray, dans mes exemples addtwo (out foo) code> modifiera
foo code>. C'est la partie par référence. Comment cela fonctionne-t-il est dépendant de la mise en œuvre, mais il sera généralement le même pour Ref et Out. Et probablement des compensations empilées au lieu des pointeurs.
Je suis désolé. Oui, il y avait un bogue dans mon code de test. Après le corriger, j'ai vu que les paramètres «sortis» ne sont pas passés à l'exception, mais sont passés à la FAE par référence avec la contrainte supplémentaire de la mission définitive. Veuillez accepter mes excuses.
Vous passez en référence quelque chose que vous souhaitez être lus et écrit par une autre fonction, vous devez donc passer la variable initialisée afin d'être correctement lu.
EDIT: Exemple: P>
void mymethod2(out string a) { a="hello"; }
Vous ne pouvez pas utiliser "OUT" et "REF 'ensemble. Il y a trois conventions d'appel dans C # (Cadre NET): P> c # n'a pas de capacité de paramètre tricielle ou hors de sortie. p> Pour voir que les paramètres "OUT" en C # ne sont pas true Paramètres, vous pouvez utiliser le code suivant: P>
Passing by value
Initial
Initial
Passing by reference with 'out' keyword
Initial
OUT
Passing by reference with 'ref' keyword
OUT
REF
out code> est pas b> en valeur.
Cela dépend de ce que vous lisez le manuel d'informatique que vous lisez, mais la plupart envisagent de tous les exemples de "Pass par valeur". Le concept essentiel de passage par valeur est que lorsqu'il est passé, vous copiez la valeur au lieu d'un pointeur. BTW, il y a cinq schémas de passage de paramètres reconnus dans tous les suivants: IN, OUT, IN-OUT, REF et NAME. C # seulement a dans, out et réf. Le passage par nom est très intéressant. Recherchez Algol-68 si vous êtes curieux.
J'ai oublié que de nombreuses langues de retour en arrière peuvent également transmettre par référence. Cela fait une différence lorsqu'ils retournent plusieurs fois, par exemple avec un appel d'appel / cc ou une langue contenant de vrais générateurs.
Mes excuses. J'étais incorrecte à propos de l'utilisation C # du mot clé "OUT". Comme Mehrdad, Henk, et d'autres, cela n'a pas dit, il ne crée pas de paramètre de sortie, mais un paramètre Réforateur avec une contrainte supplémentaire sur une affectation définitive. Désolé pour la confusion. Mon premier commentaire est précis, cependant. Je vais éditer ma réponse pour éviter toute confusion future.
Pas de soucis; Il est facile d'obtenir ce genre de choses confus. Juste pour être clair, à la fois sur et réfléchir, imposer des exigences d'affectation définitives. (1) Sur le côté de l'appelant (1a) Les variables REF doivent être définitivement attribuées avant que les variables de l'appel (1b) ne doivent pas nécessairement être attribuées avant que les variables d'appel, (1c) des variables sont datés après l'appel. (2) Sur le côté de la calle, (2a) les variables REF sont da tout au long, (2b) des variables de sortie ne sont pas-da lors de l'entrée, et (2C) des variables doivent être da avant chaque retour normal.
Oui, mon texte était trompeur. J'ai bien compris cette partie de cela, mais la façon dont j'ai dit que ce n'était pas clair. J'ai corrigé mon verbiage.
Pour distinguer les références C # / COM-Style de votre entrée / sortie / in-Out / Ref, ce que je fais habituellement est que je dis "copie-out" ou "copie en copie-copie" lorsque vous diriez simplement " sortir "ou" in-out ".
De plus, je remarque qu'il existe d'autres mécanismes de passage des paramètres autres que vos cinq. Evaluation pass-by-paresseux, par exemple, vient immédiatement à l'esprit. (Et je suis d'accord, le passe-nom d'Algol 68 est un peu bizarre.)
@Rayburns: est "Readonly-ref" non considéré comme distinct de "REF '(quand il existe)? Tandis que les types de valeur .NET sont rarement très gros, il existe de nombreux cas où la bonne façon de passer de grandes valeurs serait «Readonly-ref '(transmettre des valeurs immuables par« Readonly-Ref »devrait être autorisée, mais les transmettre par' ref ' ne devrait pas; permettre une valeur immuable d'être "passée par" REF '"mais les copier en premier, comme cela est fait avec des méthodes d'instance de type valeur dans les langues .NET, est le mal).
Utilisation du mot clé code> est utile si vous avez une méthode que vous devez renvoyer plusieurs valeur. Par exemple, consultez des méthodes telles que Utilisation de int.tryparse () code>. P>
ref code> est plus pour explicite des objets. Gardant à l'esprit que toute non primitive passée dans une méthode est intrinsèquement passée par référence, il n'y a pas beaucoup de besoin de celui-ci dans le code géré normal. En déclarant le mot-clé ref, vous indiquez que le paramètre sera probablement modifié dans le corps de la méthode et que le code d'appel doit donc en être conscient (pourquoi vous devez donc ajouter explicitement le
ref code> dans le code d'appel aussi. P>
Vous comprenez la dynamique de transmettre de toute façon. Certains scénarios de paramètres peuvent être: p>
REF INT NUM code> Pour un paramètre IN / OUT. La fonction peut em> modifier la valeur dedans. LI>
-
out INT NUM code> Comme Réfermer la fonction doit affecter une valeur à son retour. LI>
ul>
dans les paramètres de sortie généraux sont bons pour le moment où une fonction doit renvoyer plusieurs valeurs, car une fonction n'a qu'une valeur de retour (bien qu'elle puisse être composée). P>
Parfois, les fournisseurs d'accès à des données, comme certaines méthodes ADO.NET, utilisez des paramètres de sortie pour obtenir des informations en arrière. Certaines méthodes d'accès aux données Mimic Base de données stockées des procédures contenant des paramètres d'entrée / sortie. P>
EDIT: strong> Une stipulation pour les types de référence est les paramètres ref StringBuilder mot code> ou stringbuilder mot code> (par valeur) se comporter de la même manière - la chaîne L'extérieur est affecté, bien que l'implémentation sous-jacente puisse différer légèrement, car à ce stade, la mise au point est la référence et non la valeur sur le tas. P>
Facilement la meilleure et la meilleure réponse directe de tous ces temps.
Si vous comprenez C ++ peut-être que cela vous aidera:
void Foo(Bar) {} // pass by value c# (if it's a value type ;)) void Foo(Bar) {} // c++ void Foo(Bar) {} // pass by reference c# (if it's a reference type ;)) void Foo(Bar&) {} // c++ void Foo(ref Bar) {} // c# void Foo(Bar*) // c++ void Foo(out Bar) {} // c# void Foo(Bar**) {} // c++ (the contents of *Bar needs to be filled up)
Aide très appréciée p>
Votre compréhension sera améliorée par une utilisation correcte et minutieuse de la langue. P>
En passant par la valeur des moyens de copie d'un argument est passé. p> Blockquote>
Oui, cela est tout à fait exact. P>
Les modifications apportées à cette copie ne changent pas l'original. P> Blockquote>
Pas exactement. Commencez par distinguer soigneusement entre valeurs em> et Variables em>. Considérez: p>
class Foo { public int x; } ... void N() { Foo blah = new Foo(); blah.x = 0; M(blah); } ... void M(Foo foo) { foo.x = 123; // changes blah.x foo = null; // does not change blah }
Je ne comprends pas entièrement votre question ... Vous ne pouvez pas utiliser les deux
ref code> et
out code> sur le même argument. Et ces deux mots clés sont utilisés pour passer par référence.
Je pense que vous êtes mal compris que "passer par référence" et "transmettre des références par valeur"
Le mot clé
ref code> n'est utile que sur des valeurs par défaut de valeur, telles que des structures, des INT, des flotteurs, des bools et des énumérums.
ELLZ, vous peut i> transmettre une référence par référence et il y a une utilisation pour cela.
wow .. en fait je ne savais pas ça .. lol