Donc si j'écrit en utilisant une boucle foreach et que j'ai une fonction dedans qui prend un argument de l'objet itéré de la liste, et disons que je définis sa valeur pour qu'elle soit différente. Pourquoi ne dois-je pas utiliser out ou ref? Je pensais que c'était seulement passé par valeur si vous n'utilisiez pas out ou ref .... Je sais qu'une ref que vous devez avoir initialisé la variable avant et après vous devez juste avoir défini sa valeur avant le retour de la méthode.Passant Par ref et out
Il semble que vous parcouriez une liste et que vous passiez un objet dans son passé par référence. Considérez l'exemple suivant.
Exemple
class Program
{
static void Main(string[] args)
{
List<Foo> list = new List<Foo>();
list.Add(new Foo() { Bar = "1" });
list.Add(new Foo() { Bar = "2" });
foreach (var f in list)
{
Foo f2 = f;
Console.WriteLine("SetFoo Pre: " + f2.Bar);
SetFoo(f2);
Console.WriteLine("SetFoo Post: " + f2.Bar);
Console.WriteLine("SetFooRef Pre: " + f2.Bar);
SetFooRef(ref f2);
Console.WriteLine("SetFooRef Post: " + f2.Bar);
Console.WriteLine("");
}
Console.WriteLine("");
int i = 0;
// Not using ref keyword
Console.WriteLine("SetI Pre: " + i);
SetI(i);
Console.WriteLine("SetI Post: " + i);
// Using ref keyword
Console.WriteLine("SetRefI Pre: " + i);
SetRefI(ref i);
Console.WriteLine("SetRefI Post: " + i);
}
private static void SetRefI(ref int i)
{
i = 3;
Console.WriteLine("SetRefI Inside: " + i);
}
private static void SetI(int i)
{
i = 2;
Console.WriteLine("SetI Inside: " + i);
}
private static void SetFooRef(ref Foo f)
{
f.Bar = String.Format("{0} :: {1}", f.Bar, "WithRef");
Console.WriteLine("SetFooRef Inside: " + f.Bar);
}
private static void SetFoo(Foo f)
{
f.Bar = String.Format("{0} :: {1}", f.Bar, "WithoutRef");
Console.WriteLine("SetFoo Inside: " + f.Bar);
}
}
class Foo
{
public string Bar { get; set; }
}
Sortie:
setFoo Pre: 1 setFoo Intérieur: 1 ::
WithoutRef setFoo Poste: 1 WithoutRef
setFoo Pre: 1 :: WithoutRef setFoo
Intérieur: 1 :: WithoutRef :: WithRef
SetFoo Message: 1 WithoutRef :: WithRefsetFoo Pre: 2 setFoo Intérieur: 2 ::
WithoutRef setFoo Poste: 2 WithoutRef
setFoo Pre: 2 :: WithoutRef setFoo
Intérieur: 2 :: WithoutRef :: WithRef
setFoo Poste: 2 WithoutRef: : WithRefSETI Pre: 0 SETI intérieur: 2 SetIPost: 0
SetRefI Pre: 0 SetRefI intérieur: 3
SetRefI Poste: 3
Je comprends le ref avec l'exemple entier mais pas l'exemple d'itération d'objet Foo ci-dessus.
Merci!
Donc dans le cas ci-dessus, je passe une référence de l'objet Foo à mes méthodes SetFoo. Puisqu'il partage l'emplacement de la mémoire sames, si je modifie la valeur de Bar, la valeur de Bar sera la même que celle de Foo dans la liste après avoir quitté ma fonction? Donc, il n'y a pas besoin de ma méthode SetFooRef alors? – Gabe
Il est encore différent, vous passez et objet par la valeur de référence plutôt que le pointeur de référence de l'objet (pour ainsi dire) si vous n'utilisez pas le modificateur ref. Votre SetFooRef peut être utile si, disons, vous allez construire un objet Foo complètement nouveau dans la méthode - ce nouvel objet sera "vu" en dehors de la méthode. En revanche, sans ref, vous pouvez modifier les propriétés des objets, etc. et ces modifications seront "vues" à l'extérieur, mais si vous initialisez un nouvel objet Foo sur une variable de paramètre, elle n'aura qu'une portée locale. – Audrius
Ok, ça a plus de sens. Donc pour l'exemple entier, je le passe par valeur avec SetI() mais setRefI() je passe par le pointeur de référence alors? – Gabe