对象行为

时间:2010-11-18 13:10:43

标签: c#

任何人都可以解释下面代码的行为。下面代码的输出是字符串“str”,i的值是100。

但为什么会这样呢?设置对象c1 = null后,为什么不为null?

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());
    }

4 个答案:

答案 0 :(得分:5)

当您调用method2(Class1 c1)时,您正在传递对象的引用副本,而不是对象本身(或对它的引用)。设置c1 = null时,您将引用的副本设置为null,而不是对象。

您可以通过将方法签名更改为此来获得您期望的行为:

method2(ref Class1 c1)

答案 1 :(得分:4)

在C#中,引用按值传递。也就是说,method2会收到c1的引用值的副本。

method2设置中c1 = null仅影响参考的本地副本。

请参阅this article for more info

答案 2 :(得分:3)

这是一个传递引用/按值传递的东西。 Javaranch Camp site stories: Pass By Value Please解释得非常好。我知道上面的链接是针对Java的,这是一个C#问题,但是同样的事情发生了(除非使用了“ref”关键字)。

答案 3 :(得分:1)

希望简单编辑代码可以告诉您原因:

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());
}

我认为清楚地表明Class2.method2中使用的引用与main中使用的引用不同。 c1在main中声明,当在方法调用c2.method2(c1);中用作参数时,对Class1实例的引用将复制到名为myLocalReference的新本地值中。然后,您设置myLocalReference = null;,在方法2中,您会发现Response.Write(myLocalReference.method1());Response.Write(myLocalReference.i.ToString());会失败。当method2退出时,本地引用myLocalReference超出范围,您将返回到存在c1引用的main处,并且不会更改,以便后续的Response.Write方法成功。