2010-11-18 2 views
2

Quelqu'un peut-il expliquer le comportement du code ci-dessous? La sortie du code ci-dessous est la chaîne "str" ​​et la valeur de i est 100.Comportement de l'objet

Mais pourquoi est-ce le cas? Après avoir défini l'objet c1 = null, pourquoi n'est-il pas nul?

public class Class1 
{ 
    public int i; 
    public Class1() 
    { 
     i = 10; 
    }  

    public string method1() 
    { 
     return "str"; 
    } 
} 

public class Class2 
{ 
    public void method2(Class1 c1) 
    { 
     c1.i = 100; 
     c1 = null; 
    } 
} 

    void main() 
    { 
     Class1 c1 = new Class1(); 
     Class2 c2 = new Class2(); 
     c2.method2(c1); 
     Response.Write(c1.method1()); 
     Response.Write(c1.i.ToString()); 
    } 

Répondre

3

Il s'agit d'une opération de type «passer par référence/valeur de transfert». Javaranch Camp site stories: Pass By Value Please l'explique très bien. Je sais que le lien ci-dessus est pour Java, et c'est une question C#, mais la même chose se produit (à moins que le mot clé "ref" ne soit utilisé).

+0

Et voici un bon C# article spécifique de: http://www.yoda.arachsys.com/csharp/parameters.html – LukeH

+0

@LukeH votre article est un peu waffly/académique. J'aime la version java plus. –

5

Lorsque vous appelez le method2(Class1 c1), vous transmettez une copie de la référence à l'objet, pas l'objet lui-même (ou la référence à celui-ci). Lorsque vous définissez c1 = null, vous définissez la copie de la référence comme nulle, pas l'objet.

Vous pouvez obtenir le comportement que vous attendez en changeant votre signature de la méthode à ceci:

method2(ref Class1 c1)

4

En C#, les références sont passés par valeur. Autrement dit, method2 reçoit une copie de la valeur de la référence à c1.

Dans method2, le paramètre c1 = null affecte la copie locale de la référence uniquement.

Voir this article for more info

1

Il faut espérer une modification simple de votre code peut vous montrer pourquoi:

public class Class1 
{ 
    public int i; 
    public Class1() 
    { 
     i = 10; 
    }  

    public string method1() 
    { 
     return "str"; 
    } 
} 

public class Class2 
{ 
    public void method2(Class1 myLocalReference) 
    { 
     myLocalReference.i = 100; 
     myLocalReference = null; 
    } 
} 

void main() 
{ 
    Class1 c1 = new Class1(); 
    Class2 c2 = new Class2(); 
    c2.method2(c1); 
    Response.Write(c1.method1()); 
    Response.Write(c1.i.ToString()); 
} 

Je pense que cela montre clairement que la référence utilisée dans Class2.method2 n'est pas le même que celui utilisé en main. c1 est déclaré dans main, lorsqu'il est utilisé en tant que paramètre dans l'appel de méthode c2.method2(c1); la référence à vos instances Class1 est copiée dans une nouvelle valeur locale appelée myLocalReference. Vous définissez ensuite myLocalReference = null; et dans la méthode 2 vous constaterez que Response.Write(myLocalReference.method1()); ou Response.Write(myLocalReference.i.ToString()); échouerait de manière appropriée. Lorsque la méthode 2 se termine, la référence locale myLocalReference est hors de portée et vous revenez à l'emplacement principal où la référence c1 existe et reste inchangée, ce qui entraîne la réussite des méthodes Response.Write suivantes.