2

应用程序正在打印 24,但当我们知道没有 ref 关键字时,它不应该打印 18 只传递对象的副本并且对原始对象没有任何更改。我创建了一个名为 myclass 的类和一个对象 me。age 是 myclass 类中的公共变量。我已将 me.age 设置为 18 并通过方法 show 我已将其更改为 24。

class Program
{        
    static void Main(string[] args)
    {
        myclass me = new myclass();
        me.age = 18;
        show(me);
        Console.WriteLine(me.age);
        Console.ReadLine();
    }

    public static void show( myclass you)
    {
        you.age = 24;        
    }
}

class myclass
{
    public int age;
}
4

5 回答 5

2

它正在打印正确的东西。

myclass是一个对象,默认行为是在C#中传递对象的引用,所以当你不指定任何东西时,你传递引用。

但是,如果您声明struct myclass,您将拥有您想要的行为,因为默认情况下结构不是引用。

于 2013-05-23T23:42:21.833 回答
2

不要混淆变量和变量指向的内容。

当你有:

MyClass myVar = new MyClass();
MyClass myVar2 = myVar;

这将只创建一个对象的单个实例,但有 2 个变量指向它。

您的参数发生了同样的事情: you是变量的副本me,但都指向同一个对象。所以当你修改的时候you.age,你也在修改me.age

在您的功能中,如果您这样做了

you = new myClass();

只有这样才会me引用you不同的对象。如果你这样做了,me仍然会指向原始对象。

如果你添加ref了参数you,那么如果你做了

you = new myClass();

然后变量me将被更新为指向同一个对象。

对于对象,您需要将变量与变量指向的内容分开。

于 2013-05-24T00:00:28.210 回答
2

您可能将此与 C++ 类混淆了。在 C# 中,类是引用类型,这意味着只要您有一个类型为类的变量,该变量并不包含对象本身,它仅包含对它的引用(您可以将其视为指针)。因此,当您将对象传递给方法时,实际上是传递了对该对象的引用。这意味着您观察到的行为是正确的。

C# 还支持值类型(与 Java 不同),您可以使用struct而不是class. 如果您更改myclass为 a srtuct,您将获得预期的行为。

于 2013-05-24T01:12:58.113 回答
1

您混淆了值类型和引用类型。

public void addTwo(int a)
{
    a += 2;
}

...

int a = 5;
addTwo(a);
Console.WriteLine(a); // will give "5";

public void addTwo(ref int a)
{
    a += 2;
}

...

int a = 5;
addTwo(ref a);
Console.WriteLine(a); // will give "7";

对于引用类型(定义为class而不是 的任何内容struct,您传递的是对对象的引用,而不是副本。所以您实际上是在更改对象。

于 2013-05-23T23:41:15.110 回答
0

您正在向您的函数发送一个对象。

不是原子类型或结构,因此它是通过引用发送的(这就是 C# 的工作方式),您在函数中对此对象所做的任何更改也会在原始对象中更改,因为它是相同的。

有关传递参数的更多信息:http: //msdn.microsoft.com/en-us/library/0f66670z (v=vs.71).aspx

于 2013-05-23T23:41:04.730 回答