C# 为什么构造函数不';不影响本例中的属性
我想知道为什么我们有C# 为什么构造函数不';不影响本例中的属性,c#,C#,我想知道为什么我们有p=新人(“汤姆”,999)
p=新人(“汤姆”,999)通过调用fred.PrintInfo()代码>
它不会将p更改为TOM和999,而是使用p.age=99;我们可以改变fred的年龄,构造器和属性都是公共的,那么我遗漏了什么呢?我不想用这个代码做任何事情,我只想知道原因
using System;
class Person
{
public string fullName;
public int age;
public Person(string n, int a)
{
fullName = n;
age = a;
}
public void PrintInfo()
{
Console.WriteLine("{0} is {1} years old", fullName, age);
}
}
class MainClass
{
public static void SendAPersonByValue(Person p)
{
p.age = 99;
p = new Person("TOM", 999);
}
public static void Main()
{
Person fred = new Person("Fred", 12);
fred.PrintInfo();
SendAPersonByValue(fred);
fred.PrintInfo();
}
}
因为只传递人员p
的引用而不是引用的引用
您需要这样做才能通过引用传递该人员:
public static void SendAPersonByValue(ref Person p)
{
p.age = 99;
p = new Person("TOM", 999);
}
这是因为您创建了一个新引用。如果希望实现预期的行为,则必须将SendPersonByValue方法更改为ref Person p
因此,这里发生的是:
SendAPersonByValue(fred);
//You are passing the value of fred's reference here
...
public static void SendAPersonByValue(Person p)
{
p.age = 99;
//The value of Fred's reference is used to populate his age
p = new Person("TOM", 999);
//p is now assigned to a totally new reference.
//Because value's are immutable, fred remains
//However, p is now pointing to a different reference value
}
将ref添加到方法签名时会发生什么情况:
SendAPersonByValue(ref fred);
//A reference (pointer) to Fred's reference value is passed
...
public static void SendAPersonByValue(Person p)
{
p.age = 99;
//The pointer of the reference of Fred is used to populate his age
//Ultimately, this is the same as above because the both end up at Fred
p = new Person("TOM", 999);
//The reference value of p (fred) is now the new reference
//since it was just a pointer to the reference value
}
如果您希望主体中的person引用更改为新引用,则必须将ref放入参数列表中。否则,堆栈将引用main使用的位置。它可以更改内部属性,但不能更改main对它传入的项的引用。在方法sendpersonbyvalue(Person p)
中指定变量p时,只能在本地指定它。它不会在您的main方法中更改fred
您可以返回修改后的person并在main方法中替换fred,也可以使用ref
关键字。fred
指向内存中的某个特定位置:
+------------+
fred ----> | Fred 12 |
+------------+
+------------+
fred ----> | Fred 99 |
+------------+
^
p ---------+
调用sendpersonbyvalue时,p
指向相同的位置:
+------------+
fred ----> | Fred 12 |
+------------+
^
p ---------+
p.age=99代码>现在更改内存中的值:
+------------+
fred ----> | Fred 12 |
+------------+
+------------+
fred ----> | Fred 99 |
+------------+
^
p ---------+
鉴于新人(“TOM”,999)
在内存中创建一个新的人,并且p=…
使p
指向它:
+------------+
fred ----> | Fred 99 |
+------------+
+------------+
p ----> | TOM 999 |
+------------+
这就是为什么fred
仍然包含fred,99
现在,如果您要将fred
作为密码传递,p
将成为fred
的别名:
+------------+
fred/p ----> | Fred 12 |
+------------+
p.age=99后
+------------+
fred/p ----> | Fred 99 |
+------------+
之后p=新人(“汤姆”,999)代码>:
读这个…:这是一个很好的老派视觉解释。喜欢图表中的加号、减号和管道。:)+1.回答这个问题。甚至帮助我更清楚地理解它。我非常喜欢它。谢谢你。我知道引用,但你在清除指针所做的事情方面帮了我很多。Approved一旦引用不再使用,它会立即被标记为垃圾收集。顺便说一句,干得好+1.