Question

Je fais un usage intensif de l'héritage, du polymorphisim et de l'encapsulation, mais je viens de me rendre compte que je ne connaissais pas le comportement suivant concernant la portée d'un objet par rapport à une variable. La différence est mieux illustrée avec le code:

public class Obj
{
    public string sss {get; set;}

    public Obj()
    {
        sss = "0";
    } 
}     

public partial class testScope : System.Web.UI.Page
 {
    protected void Page_Load(object sender, EventArgs e)
    { 
        Obj a = new Obj(); 
        String sss = "0";            
        Context.Response.Write(sss); // 0

        FlipString(sss);
        FlipString(a.sss);
        Context.Response.Write(sss + a.sss); // 0 0

        FlipObject(a);
        Context.Response.Write(a.sss); // 1
        Context.Response.End();
    }

    public void FlipString(string str)
    { str = "1"; }

    public void FlipObject(Obj str)
    { str.sss = "1"; }
}

J'ai donc pensé que lorsqu'une variable est transmise à une méthode, les modifications sont limitées à la portée de la méthode. Mais il semble que si un objet est passé dans une méthode, les modifications apportées à ses propriétés vont au-delà de la méthode.

Je pouvais accepter cela si la règle était que ce comportement existait pour les objets et non pour les variables, mais que dans .net tout est un objet, une chaîne (comme celle de l'exemple, System.String). Alors, quelle est la règle, comment Je prédis la portée d'un paramètre que je passe dans une méthode?

Était-ce utile?

La solution

Vous ne transmettez jamais un objet en tant qu'argument. Vous ne transmettez jamais qu'une référence ou une valeur de type valeur. À moins que vous n'utilisiez le mot clé ref , les arguments sont passés par valeur - la valeur initiale du paramètre correspond à la valeur évaluée de l'argument et les modifications apportées à la valeur du paramètre ne sont pas visibles par l'appelant. .

Cependant, il est très important de comprendre que la valeur du paramètre (pour un type de référence) est juste la référence . Si vous modifiez le contenu de l'objet auquel la référence fait référence, ce changement sera visible par l'appelant.

C’est un sujet qui mérite plus que quelques paragraphes - Je vous suggère de lire mon article sur le paramètre passer en .NET pour plus d'informations.

Autres conseils

Je pense que je viens de le découvrir, certaines choses dans .net sont "valeur". les types et autres sont " référence " types, donc pour les types valeur, la valeur est dupliquée lorsqu’elle est marshalée dans une méthode, mais les types de référence ont un pointeur similaire, ou une référence passée dans la méthode qui partage évidemment la même étendue que le parent. Ma question est donc de savoir comment savoir si quelque chose correspond à un type de valeur ou non. Je vois que les structures telles que ints sont toutes des types valeur, mais les chaînes semblent se comporter comme des structures même s’il s’agit d’objets System.String?

Une classe (Obj dans votre cas) est un type de référence Ainsi, lorsque vous appelez la fonction, vous transmettez en réalité une référence (vous pouvez en principe considérer cela comme un pointeur de type sécurisé) à cet objet. Si vous souhaitez empêcher les modifications apportées aux objets mutables (types de classe / référence), vous devez alors cloner cet objet avant de le transmettre à la fonction appropriée (ou simplement envisager de le transformer en structure copiée par valeur).

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