对于C#中引用类型的变量如何工作,初学者有一个常见的误解。
让我们看一个更简单的例子:
class F1
{
static int x = 0;
public static int Start()
{
x = 1;
return x;
}
public static void Stop()
{
x = 0;
}
}
class F2
{
int y;
void DoIt()
{
this.y = F1.Start();
F1.Stop();
Console.WriteLine(this.y);
}
}
假设我们在F2的一个实例上调用DoIt。的价值是什么
this.y
?
跟踪程序的操作:
-
F1。x从零开始。
-
F2。DoIt调用F1。开始()
-
F1。x变为1
-
F1。Start()返回1
-
F2。y变为1
-
F2。DoIt调用F1。停止()
-
F1。x变为0
F2。y仍然是1。更改F2。x对F2没有任何改变。y、 这是一个完全不同的变量。我们没有创造任何一种神奇的连接,即“当你读F2.y时,真正读F2.x的当前值”。
在您的程序中也是如此。我们可以将其更改为引用类型,但不会更改:
class F1
{
public static F1 x = null;
public static F1 Start()
{
x = new F1();
return x;
}
public static void Stop()
{
x = null;
}
}
class F2
{
F1 y;
void DoIt()
{
this.y = F1.Start();
F1.Stop();
Console.WriteLine(this.y == null); // false
}
}
发生了什么?同样的事情。
-
F1。x以null开头。
-
F2。DoIt调用F1。开始()
-
F1。x成为对有效对象的引用
-
F1。Start()返回对有效对象的引用
-
F2。y成为对有效对象的引用
-
F2。DoIt调用F1。停止()
-
F1。x变为空
F2是什么。Y
仍然是对有效对象的引用
.F2。y是
从不
对F1的引用。x、 它们都是对同一有效对象的引用。
引用是值,就像整数一样
。
现在,如果你
希望
要为变量创建别名,C#7允许您执行以下操作:
class F1
{
static int x = 0;
public static ref int Start()
{
x = 1;
return ref x;
}
public static void Stop()
{
x = 0;
}
}
class F2
{
void DoIt()
{
ref int y = ref F1.Start();
F1.Stop();
Console.WriteLine(y); // 0
}
}
这个
ref
方法
局部变量y是变量F1的别名。十、
,所以当我们改变
F2.x
,我们改变
y
还有,因为他们只有两个人
名称
对于
相同的变量
;他们是
别名
。
请注意,变量的别名
与变量的类型无关
。您可以为int变量创建别名,也可以为对象变量创建别名,等等。别名变量和别名局部必须具有完全相同的类型(练习:为什么?)但是那种类型可以是你想要的任何类型。
但规则是:
别名变量可以是任何变量;别名变量只能是局部或形式参数
例如,无法创建“ref int”字段。请注意
ref int y
是一个
地方的
,不是
领域
。
返回变量别名是一项高级功能,我们多年来一直在争论是否应该将其添加到C#。
在对C语言中的引用语义有了透彻而深入的理解之前,不应该使用此功能#
。