Question

Je crée une fonction où je dois passer un objet afin qu'il puisse être modifié par la fonction. Quelle est la différence entre:

public void myFunction(ref MyClass someClass)

et

public void myFunction(out MyClass someClass)

Lequel dois-je utiliser et pourquoi?

Était-ce utile?

La solution

ref dit au compilateur que l'objet est initialisé avant d'entrer dans la fonction, tandis que out Indique au compilateur que l'objet sera initialisé à l'intérieur de la fonction.

Donc pendant ref est à deux voies, out est à l'extérieur.

Autres conseils

La ref Le modificateur signifie que:

  1. La valeur est déjà définie et
  2. La méthode peut la lire et la modifier.

La out Le modificateur signifie que:

  1. La valeur n'est pas définie et ne peut pas être lue par la méthode jusqu'à il est défini.
  2. La méthode devoir Réglez-le avant de revenir.

Disons que Dom se présente dans la cabine de Peter sur la mémo sur les rapports TPS.

Si Dom était un argument de référence, il aurait une copie imprimée du mémo.

Si Dom était un argument Out, il ferait de Peter imprimer une nouvelle copie de la note à emporter avec lui.

Je vais m'essayer à une explication:

Je pense que nous comprenons comment les types de valeur fonctionnent, non? Les types de valeur sont (int, long, struct, etc.). Lorsque vous les envoyez dans une fonction sans commande de refonte, il copie le Les données. Tout ce que vous faites à ces données dans la fonction affecte uniquement la copie, pas l'original. La commande Ref envoie les données réelles et toute modification affectera les données en dehors de la fonction.

OK sur la partie déroutante, types de référence:

Permet de créer un type de référence:

List<string> someobject = new List<string>()

Quand tu es nouveau certains objet, deux parties sont créées:

  1. Le bloc de mémoire qui contient des données pour certains objet.
  2. Une référence (pointeur) sur ce bloc de données.

Maintenant, quand vous envoyez certains objet dans une méthode sans refiter il copie le référence pointeur, pas les données. Vous avez donc maintenant ceci:

(outside method) reference1 => someobject
(inside method)  reference2 => someobject

Deux références pointant vers le même objet. Si vous modifiez une propriété sur certains objet En utilisant la référence2, il affectera les mêmes données indiquées par la référence1.

 (inside method)  reference2.Add("SomeString");
 (outside method) reference1[0] == "SomeString"   //this is true

Si vous null Out Reference2 ou le pointez vers de nouvelles données, il n'affectera pas la référence1 ni la référence des données 1.

(inside method) reference2 = new List<string>();
(outside method) reference1 != null; reference1[0] == "SomeString" //this is true

The references are now pointing like this:
reference2 => new List<string>()
reference1 => someobject

Maintenant, que se passe-t-il lorsque vous envoyez certains objet par ref à une méthode? La référence réelle à certains objet est envoyé à la méthode. Vous n'avez donc plus qu'une seule référence aux données:

(outside method) reference1 => someobject;
(inside method)  reference1 => someobject;

mais qu'est ce que ça veut dire? Il agit exactement la même chose que l'envoi de certains objets non par référence, sauf pour deux choses principales:

1) Lorsque vous nulrez la référence à l'intérieur de la méthode, elle nulra celle en dehors de la méthode.

 (inside method)  reference1 = null;
 (outside method) reference1 == null;  //true

2) Vous pouvez désormais indiquer la référence à un emplacement de données complètement différent et la référence en dehors de la fonction pointera désormais vers le nouvel emplacement de données.

 (inside method)  reference1 = new List<string>();
 (outside method) reference1.Count == 0; //this is true

Ref est dans et dehors.

Tu devrais utiliser out de préférence partout où il suffit pour vos exigences.

dehors:

Dans C #, une méthode ne peut renvoyer qu'une seule valeur. Si vous aimez renvoyer plus d'une valeur, vous pouvez utiliser le mot clé OUT. Le modificateur out retour en tant que retour par référence. La réponse la plus simple est que le mot-clé «Out» est utilisé pour obtenir la valeur de la méthode.

  1. Vous n'avez pas besoin d'initialiser la valeur dans la fonction d'appel.
  2. Vous devez attribuer la valeur dans la fonction appelée, sinon le compilateur rapportera une erreur.

Réf:

En C #, lorsque vous passez un type de valeur tel que int, float, double etc. En argument au paramètre de la méthode, il est passé par valeur. Par conséquent, si vous modifiez la valeur du paramètre, cela n'affecte pas l'argument dans l'appel de la méthode. Mais si vous marquez le paramètre avec le mot clé «Ref», il se reflétera dans la variable réelle.

  1. Vous devez initialiser la variable avant d'appeler la fonction.
  2. Il n'est pas obligatoire d'attribuer une valeur au paramètre REF dans la méthode. Si vous ne modifiez pas la valeur, quel est le besoin de le marquer comme «réf»?

Étendre le chien, exemple de chat. La deuxième méthode avec REF modifie l'objet référencé par l'appelant. D'où "chat" !!!

    public static void Foo()
    {
        MyClass myObject = new MyClass();
        myObject.Name = "Dog";
        Bar(myObject);
        Console.WriteLine(myObject.Name); // Writes "Dog". 
        Bar(ref myObject);
        Console.WriteLine(myObject.Name); // Writes "Cat". 
    }

    public static void Bar(MyClass someObject)
    {
        MyClass myTempObject = new MyClass();
        myTempObject.Name = "Cat";
        someObject = myTempObject;
    }

    public static void Bar(ref MyClass someObject)
    {
        MyClass myTempObject = new MyClass();
        myTempObject.Name = "Cat";
        someObject = myTempObject;
    }

Puisque vous passez dans un type de référence (une classe), il n'est pas nécessaire d'utiliser ref Parce que par défaut seulement un référence à l'objet réel est passé et donc vous modifiez toujours l'objet derrière la référence.

Exemple:

public void Foo()
{
    MyClass myObject = new MyClass();
    myObject.Name = "Dog";
    Bar(myObject);
    Console.WriteLine(myObject.Name); // Writes "Cat".
}

public void Bar(MyClass someObject)
{
    someObject.Name = "Cat";
}

Tant que vous passez dans une classe que vous n'avez pas à utiliser ref Si vous souhaitez modifier l'objet à l'intérieur de votre méthode.

ref et out se comporter de la même manière, sauf les différences suivantes.

  • ref La variable doit être initialisée avant utilisation. out la variable peut être utilisée sans affectation
  • out Le paramètre doit être traité comme une valeur non attribuée par la fonction qui l'utilise. Ainsi, nous pouvons utiliser initialisé out Paramètre dans le code d'appel, mais la valeur sera perdue lorsque la fonction s'exécutera.

Pour ceux qui apprennent par l'exemple (comme moi), voici ce Anthony Kolesov dit.

J'ai créé quelques exemples minimaux de référence, de sortie et d'autres pour illustrer le point. Je ne couvre pas les meilleures pratiques, juste des exemples pour comprendre les différences.

https://gist.github.com/2upmedia/6d98a57b68d849ee7091

"Boulanger"

C'est parce que le premier modifie votre référence de chaîne pour pointer vers "Baker". La modification de la référence est possible car vous l'avez transmise via le mot clé ref (=> une référence à une référence à une chaîne). Le deuxième appel obtient une copie de la référence à la chaîne.

String semble d'abord une sorte de spécial. Mais String n'est qu'une classe de référence et si vous définissez

string s = "Able";

alors s est une référence à une classe de chaîne qui contient le texte "capable"! Une autre affectation à la même variable via

s = "Baker";

ne change pas la chaîne d'origine mais crée simplement une nouvelle instance et laisse S vers cette instance!

Vous pouvez l'essayer avec le petit code suivant Exemple:

string s = "Able";
string s2 = s;
s = "Baker";
Console.WriteLine(s2);

Qu'attendez-vous? Ce que vous obtiendrez est toujours "capable" car il vous suffit de définir la référence dans S sur une autre instance tandis que S2 pointe vers l'instance d'origine.

EDIT: La chaîne est également immuable, ce qui signifie qu'il n'y a tout simplement pas de méthode ou de propriété qui modifie une instance de chaîne existante (vous pouvez essayer d'en trouver une dans les documents mais vous n'aurez pas fini :-)). Toutes les méthodes de manipulation de chaîne renvoient une nouvelle instance de chaîne! (C'est pourquoi vous obtenez souvent de meilleures performances lorsque vous utilisez la classe StringBuilder)

référence signifie que la valeur du paramètre REF est déjà définie, la méthode peut la lire et la modifier. L'utilisation du mot-clé ref est la même chose que de dire que l'appelant est responsable de l'initialisation de la valeur du paramètre.


dehors Dit au compilateur que l'initialisation de l'objet est la responsabilité de la fonction, la fonction doit attribuer au paramètre OUT. Il n'est pas autorisé à le laisser non attribué.

Dehors: Une instruction de retour peut être utilisée pour renvoyer une seule valeur à partir d'une fonction. Cependant, en utilisant des paramètres de sortie, vous pouvez renvoyer deux valeurs à partir d'une fonction. Les paramètres de sortie sont comme des paramètres de référence, sauf qu'ils transfèrent des données hors de la méthode plutôt que de lui.

L'exemple suivant illustre ceci:

using System;

namespace CalculatorApplication
{
   class NumberManipulator
   {
      public void getValue(out int x )
      {
         int temp = 5;
         x = temp;
      }

      static void Main(string[] args)
      {
         NumberManipulator n = new NumberManipulator();
         /* local variable definition */
         int a = 100;

         Console.WriteLine("Before method call, value of a : {0}", a);

         /* calling a function to get the value */
         n.getValue(out a);

         Console.WriteLine("After method call, value of a : {0}", a);
         Console.ReadLine();

      }
   }
}

Réf:Un paramètre de référence est une référence à un emplacement de mémoire d'une variable. Lorsque vous transmettez les paramètres par référence, contrairement aux paramètres de valeur, un nouvel emplacement de stockage n'est pas créé pour ces paramètres. Les paramètres de référence représentent le même emplacement de mémoire que les paramètres réels fournis à la méthode.

En C #, vous déclarez les paramètres de référence à l'aide du mot clé ref. L'exemple suivant le démontre:

using System;
namespace CalculatorApplication
{
   class NumberManipulator
   {
      public void swap(ref int x, ref int y)
      {
         int temp;

         temp = x; /* save the value of x */
         x = y;   /* put y into x */
         y = temp; /* put temp into y */
       }

      static void Main(string[] args)
      {
         NumberManipulator n = new NumberManipulator();
         /* local variable definition */
         int a = 100;
         int b = 200;

         Console.WriteLine("Before swap, value of a : {0}", a);
         Console.WriteLine("Before swap, value of b : {0}", b);

         /* calling a function to swap the values */
         n.swap(ref a, ref b);

         Console.WriteLine("After swap, value of a : {0}", a);
         Console.WriteLine("After swap, value of b : {0}", b);

         Console.ReadLine();

      }
   }
}

Ref and Out travaille comme passer par références et passer par des pointeurs comme dans C ++.

Pour REF, l'argument doit être déclaré et initialisé.

Car à l'extérieur, l'argument doit déclarer mais peut être initialisé ou non

        double nbr = 6; // if not initialized we get error
        double dd = doit.square(ref nbr);

        double Half_nbr ; // fine as passed by out, but inside the calling  method you initialize it
        doit.math_routines(nbr, out Half_nbr);

Temps de création:

(1) Nous créons la méthode d'appel Main()

(2) il crée un objet de liste (qui est un objet de type de référence) et le stocke dans la variable myList.

public sealed class Program 
{
    public static Main() 
    {
        List<int> myList = new List<int>();

Pendant l'exécution:

(3) L'exécution alloue une mémoire sur la pile à # 00, suffisamment large pour stocker une adresse (# 00 = myList, car les noms de variables ne sont vraiment que des alias pour les emplacements de la mémoire)

(4) L'exécution crée un objet de liste sur le tas à la mémoire de la mémoire #FF (toutes ces adresses sont par exemple SAKES)

(5) L'exécution stockerait ensuite l'adresse de départ #ff de l'objet au # 00 (ou en mots, stocke la référence de l'objet de liste dans le pointeur myList)

Retour au temps de création:

(6) Nous passons ensuite l'objet de liste comme argument myParamList à la méthode appelée modifyMyList et y attribuer un nouvel objet de liste

List<int> myList = new List<int>();

List<int> newList = ModifyMyList(myList)

public List<int> ModifyMyList(List<int> myParamList){
     myParamList = new List<int>();
     return myParamList;
}

Pendant l'exécution:

(7) L'exécution démarre la routine d'appel pour la méthode appelée et dans le cadre de celui-ci, vérifie le type de paramètres.

(8) Lors de la recherche du type de référence, il répartit une mémoire sur la pile à # 04 pour alimenter la variable de paramètre myParamList.

(9) Il stocke ensuite la valeur #ff dedans.

(10) L'exécution crée un objet de liste sur le tas à l'emplacement de la mémoire # 004 et remplace #FF dans # 04 par cette valeur (ou déréférencé par l'objet de liste d'origine et pointé vers le nouvel objet de liste dans cette méthode)

L'adresse dans # 00 n'est pas modifiée et conserve la référence à #FF (ou à l'original myList Le pointeur n'est pas perturbé).


La référence Le mot clé est une directive de compilateur pour sauter la génération de code d'exécution pour (8) et (9), ce qui signifie qu'il n'y aura pas d'allocation de tas pour les paramètres de la méthode. Il utilisera le pointeur # 00 original pour fonctionner sur l'objet à #ff. Si le pointeur d'origine n'est pas initialisé, l'exécution s'arrêtera en se plaignant qu'il ne peut pas continuer car la variable n'est pas initialisée

La dehors Le mot clé est une directive de compilateur qui est à peu près la même que Ref avec une légère modification à (9) et (10). Le compilateur s'attend à ce que l'argument ne soit pas initialisé et se poursuivra avec (8), (4) et (5) pour créer un objet sur tas et stocke son adresse de départ dans la variable d'argument. Aucune erreur non initialisée ne sera lancée et toute référence précédente stockée ne sera perdue.

Ils sont à peu près les mêmes - la seule différence est qu'une variable que vous passez en tant que paramètre OUT n'a pas besoin d'être initialisée, et la méthode utilisant le paramètre Ref doit la définir sur quelque chose.

int x;    Foo(out x); // OK 
int y;    Foo(ref y); // Error

Les paramètres REF sont destinés aux données qui pourraient être modifiées, les paramètres OUT sont destinés aux données qui sont une sortie supplémentaire pour la fonction (par exemple int.tr.tryParse) qui utilisent déjà la valeur de retour pour quelque chose.

Ci-dessous, j'ai montré un exemple en utilisant les deux Référence et dehors. Maintenant, vous serez tous effacés de la référence et de la sortie.

Dans l'exemple mentionné ci-dessous lorsque je commente // myrefobj = new myClass {name = "ref Outside appelé !!"};ligne, obtiendra une erreur disant "Utilisation de la variable locale non attribuée 'myrefobj'", mais il n'y a pas une telle erreur dans dehors.

Où utiliser Ref: Lorsque nous appelons une procédure avec un paramètre In et que le même paramètre sera utilisé pour stocker la sortie de ce proc.

Où utiliser: Lorsque nous appelons une procédure avec NO dans le paramètre et que le même param sera utilisé pour renvoyer la valeur de ce proc. Notez également la sortie

public partial class refAndOutUse : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        myClass myRefObj;
        myRefObj = new myClass { Name = "ref outside called!!  <br/>" };
        myRefFunction(ref myRefObj);
        Response.Write(myRefObj.Name); //ref inside function

        myClass myOutObj;
        myOutFunction(out myOutObj);
        Response.Write(myOutObj.Name); //out inside function
    }

    void myRefFunction(ref myClass refObj)
    {
        refObj.Name = "ref inside function <br/>";
        Response.Write(refObj.Name); //ref inside function
    }
    void myOutFunction(out myClass outObj)
    {
        outObj = new myClass { Name = "out inside function <br/>" }; 
        Response.Write(outObj.Name); //out inside function
    }
}

public class myClass
{
    public string Name { get; set; }
} 
 public static void Main(string[] args)
    {
        //int a=10;
        //change(ref a);
        //Console.WriteLine(a);
        // Console.Read();

        int b;
        change2(out b);
        Console.WriteLine(b);
        Console.Read();
    }
    // static void change(ref int a)
    //{
    //    a = 20;
    //}

     static void change2(out int b)
     {
         b = 20;
     }

Vous pouvez vérifier ce code, il vous décrira sa différence complète lorsque vous utilisez "Ref", c'est signifie que vous initialisez déjà cet int / chaîne

Mais lorsque vous utilisez "OUT", cela fonctionne dans les deux conditions si vous initialisez cette int / chaîne ou non, mais vous devez initialiser cette int / chaîne dans cette fonction

REF: Le mot-clé Ref est utilisé pour passer un argument comme référence. Cela signifie que lorsque la valeur de ce paramètre est modifiée dans la méthode, elle se reflète dans la méthode d'appel. Un argument qui est passé à l'aide d'un mot-clé Ref doit être initialisé dans la méthode d'appel avant d'être transmis à la méthode appelée.

OUT: Le mot-clé Out est également utilisé pour transmettre un argument comme le mot clé REF, mais l'argument peut être passé sans y attribuer de valeur. Un argument qui est passé à l'aide d'un mot-clé OUT doit être initialisé dans la méthode appelée avant de revenir à la méthode d'appel.

public class Example
{
 public static void Main() 
 {
 int val1 = 0; //must be initialized 
 int val2; //optional

 Example1(ref val1);
 Console.WriteLine(val1); 

 Example2(out val2);
 Console.WriteLine(val2); 
 }

 static void Example1(ref int value) 
 {
 value = 1;
 }
 static void Example2(out int value) 
 {
 value = 2; 
 }
}

/* Output     1     2     

Ref et sortir dans la surcharge de méthode

Ref et Out ne peuvent pas être utilisés dans la surcharge de méthode simultanément. Cependant, Ref et Out sont traités différemment au moment de l'exécution, mais ils sont traités de la même manière au moment de la compilation (CLR ne fait pas la différence entre les deux pendant qu'il a créé l'IL pour Ref et Out).

Du point de vue d'une méthode qui reçoit un paramètre, la différence entre ref et out est-ce que C # exige que les méthodes doivent écrire à chaque out paramètre avant de revenir, et ne doit rien faire avec un tel paramètre, autre que de le passer en tant que out paramètre ou en écrivant, jusqu'à ce qu'il soit passé comme un out paramètre vers une autre méthode ou écrit directement. Notez que certaines autres langues n'imposent pas de telles exigences; une méthode virtuelle ou d'interface qui est déclarée en C # avec un out Le paramètre peut être remplacé dans une autre langue qui n'impose aucune restriction spéciale à ces paramètres.

Du point de vue de l'appelant, C # supposera dans de nombreuses circonstances lors de l'appel d'une méthode avec un out Le paramètre entraînera l'écriture de la variable passée sans avoir été lue en premier. Cette hypothèse peut ne pas être correcte lors de l'appel des méthodes écrites dans d'autres langues. Par exemple:

struct MyStruct
{
   ...
   myStruct(IDictionary<int, MyStruct> d)
   {
     d.TryGetValue(23, out this);
   }
}

Si myDictionary identifie un IDictionary<TKey,TValue> implémentation écrite dans une langue autre que C #, même si MyStruct s = new MyStruct(myDictionary); ressemble à une mission, elle pourrait potentiellement partir s non modifié.

Notez que les constructeurs écrits en VB.net, contrairement à ceux de C #, ne font aucune hypothèse sur la question de savoir si les méthodes appelés modifieront toute autre out paramètres, et effacez tous les champs inconditionnellement. Le comportement étrange mentionné ci-dessus ne se produira pas avec le code écrit entièrement en VB ou entièrement en C #, mais peut se produire lorsque le code écrit en C # appelle une méthode écrite dans VB.NET.

Si vous souhaitez transmettre votre paramètre en tant que référence, vous devez l'initialiser avant de passer le paramètre au compilateur de fonction Else lui-même affichera l'erreur. Mais en cas de paramètre OUT, vous n'avez pas besoin d'initialiser le paramètre de l'objet avant de le passer au Method.Vous pouvez initialiser l'objet dans la méthode d'appel elle-même.

En plus de vous permettre de réaffecter la variable de quelqu'un d'autre à une instance différente d'une classe, renvoie plusieurs valeurs, etc., utilisant ref ou out permet à quelqu'un d'autre de savoir ce dont vous avez besoin et ce que vous avez l'intention de faire avec la variable qu'ils fournissent

  • Tu Ne avez pas besoin ref ou out Si tout ce que vous allez faire est de modifier les choses à l'intérieur la MyClass instance qui est passé dans l'argument someClass.

    • La méthode d'appel verra des changements comme someClass.Message = "Hello World" si vous utilisez ref, out ou rien
    • L'écriture someClass = new MyClass() à l'intérieur myFunction(someClass) échange l'objet vu par le someClass Dans le cadre du myFunction Méthode uniquement. La méthode d'appel connaît toujours l'original MyClass Instance qu'il a créé et transmis à votre méthode
  • Tu besoin ref ou out Si vous prévoyez d'échanger le someClass Out pour un tout nouvel objet et que la méthode d'appel voient votre changement

    • L'écriture someClass = new MyClass() à l'intérieur myFunction(out someClass) change l'objet vu par la méthode qui a appelé myFunction

D'autres programmeurs existent

Et ils veulent savoir ce que vous allez faire avec leurs données. Imaginez que vous écrivez une bibliothèque qui sera utilisée par des millions de développeurs. Vous voulez qu'ils sachent ce que vous allez faire avec leurs variables lorsqu'ils appellent vos méthodes

  • Utilisant ref fait une déclaration de "passer une variable attribuée à une valeur lorsque vous appelez ma méthode. Sachez que je pourrais le changer pour quelque chose d'autre entièrement au cours de ma méthode. Ne vous attendez pas à ce que votre variable pointe vers l'ancien objet lorsque J'ai fini"

  • Utilisant out fait une déclaration de "passer une variable d'espace réservé à ma méthode. Peu importe qu'elle ait une valeur ou non; le compilateur me forcera à l'affecter à une nouvelle valeur. Je garantis absolument que l'objet pointé par votre variable Avant d'appeler ma méthode, sera être différent au moment où j'ai fini

Au fait, en C # 7.2, il y a un in Modificateur aussi

Et cela empêche la méthode d'échanger le pass passé dans le cas pour une instance différente. Pensez-y comme dire à ces millions de développeurs "passez-moi votre référence variable d'origine, et je promets de ne pas échanger vos données soigneusement conçues pour autre chose". in a quelques particularités, et dans certains cas comme lorsqu'une conversion implicite pourrait être nécessaire pour rendre votre court compatible avec un in int Le compilateur fera temporairement un INT, élargira votre court-circuit, le passera par référence et terminer. Cela peut le faire parce que vous avez déclaré que vous n'alliez pas jouer avec.


Microsoft l'a fait avec le .TryParse Méthodes sur les types numériques:

int i = 98234957;
bool success = int.TryParse("123", out i);

En signalant le paramètre comme out Ils déclarent activement ici "Nous sommes absolument va changer votre valeur minutieusement conçue de 98234957 pour autre chose "

Bien sûr, ils doivent un peu à le faire, pour des choses comme des types de valeur d'analyse parce que si la méthode d'analyse n'était pas autorisée à échanger le type de valeur pour quelque chose d'autre, cela ne fonctionnerait pas très bien. Mais imaginez qu'il y avait une méthode fictive dans certains bibliothèque que vous créez:

public void PoorlyNamedMethod(out SomeClass x)

Vous pouvez voir que c'est un out, et vous pouvez donc savoir que si vous passez des heures à croquer des numéros, créant la Someclass parfaite:

SomeClass x = SpendHoursMakingMeAPerfectSomeClass();
//now give it to the library
PoorlyNamedMethod(out x);

Eh bien, c'était une perte de temps, prendre toutes ces heures pour faire cette classe parfaite. Il va certainement être jeté et remplacé par malnamedMethod

Gardez bien que le paramètre de référence qui est transmis à l'intérieur de la fonction est directement fonctionné.

Par exemple,

    public class MyClass
    {
        public string Name { get; set; }
    }

    public void Foo()
    {
        MyClass myObject = new MyClass();
        myObject.Name = "Dog";
        Bar(myObject);
        Console.WriteLine(myObject.Name); // Writes "Dog".
    }

    public void Bar(MyClass someObject)
    {
        MyClass myTempObject = new MyClass();
        myTempObject.Name = "Cat";
        someObject = myTempObject;
    }

Cela écrira un chien, pas un chat. Par conséquent, vous devez travailler directement sur certains objets.

Je ne suis peut-être pas si bon dans ce domaine, mais les cordes (même si elles sont techniquement des types de référence et vivent sur le tas) sont passées par valeur, pas pour référence?

        string a = "Hello";

        string b = "goodbye";

        b = a; //attempt to make b point to a, won't work.

        a = "testing";

        Console.WriteLine(b); //this will produce "hello", NOT "testing"!!!!

C'est pourquoi vous avez besoin de référence si vous voulez que des changements existent en dehors de la portée de la fonction les faisant, vous ne passez pas de référence autrement.

Pour autant que je sache, vous n'avez besoin que de REF pour les types de structures / de valeur et la chaîne elle-même, car String est un type de référence qui prétend qu'il est mais n'est pas un type de valeur.

Mais je pourrais me tromper ici, je suis nouveau.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top