可链接的变量类型
本文关键字:类型 变量 链接 | 更新日期: 2023-09-27 18:16:18
哪些变量类型可以链接?我尝试使用对象,但它没有做我想要的。
object a;
object b;
b = 5;
a = b;
b = 2;
label1.Text = Convert.ToString(a);
它写 5,但我希望它是 2。
这是对引用及其工作原理以及变量的简单误解。
object a; // a is a storage location
// it holds references to instances of object
object b; // b is a storage location
//it holds references to instances of object
b = 5; // "boxes" 5 into an instance of object
// and assigns reference to that object to b
a = b; // assigns reference in storage location b to storage location a
b = 2; // "boxes" 2 into an instance of object
// and assign reference to that object to b
可以这样想。 a
和b
是一张纸,上面写着房屋的地址。当你说b = 5
时,可以把它想象成在纸上写下家庭5
b
的地址。当你说a = b
时,可以把它想象成将写在b
上的地址复制到a
。当你说b = 2
时,可以把它想象成擦除写在b
上的地址,并将其替换为家庭2
的地址。此操作不会更改写入纸a
上的值。这就是这里正在发生的事情。
现在,让我们看一个非常简单的方法来使你正在尝试做的事情发挥作用。
class MyValue {
public int Value { get; set; }
}
MyValue b = new MyValue { Value = 5 };
MyValue a = b;
b.Value = 2;
现在,如果你说
Console.WriteLine(a.Value);
会发生什么?让我们仔细推理。再一次,回到a
和b
的类比,就像写有地址的纸片。我们已经说过MyValue b = new MyValue { Value = 5 }
.把它想象成在一张纸上写下b
一个家的地址,在前门上方有一个写着5
的标志。将a = b
视为将写在b
上的地址复制到a
。然后,将b.Value = 2
视为更改前门上方标志上的值,在这种情况下,将5
更改为 2
。现在,如果有人问,写在纸a
上的房屋门上方的价值是多少?好吧,a
上的地址与b
上的地址相同。我们只是将前门上方标志上的值从 5
更改为 2
。所以,我们希望看到2
.
,尝试一下,您将看到2
打印到控制台的值。
一遍又一遍地思考这个问题,直到你觉得它深入你的骨子里。在你掌握这个基本概念之前,你会发现关于编程的推理是非常具有挑战性的。
Jason 的回答很好;要添加更多内容:
当你说a = b
时,你似乎期望这意味着a
和b
现在是同一变量的别名。这不是它的意思; a = b
是指将存储位置的内容b
复制到存储位置a
,而不是重新标记存储位置a
。
然而,有一种方法可以使两个变量相互别名;事实上,在C#中有三种方法可以做到这一点(除了Jason建议的技术之外,这可能是最好的(。
第一种方法是使用 ref
和 out
参数:
class P
{
static object b = 5;
static void M(ref object a)
{
b = 2;
Console.WriteLine(a);
}
static void Main()
{
M(ref b);
}
}
如果你运行它,你会看到它做了你想要的。 b
以 5
开头,则ref
表示a
和b
成为别名。当b
改为2
时,a
也是因为它们是同一个变量,有两个不同的名称。
但是,在单个方法中无法执行此操作。 底层运行时确实支持这一点,我曾经制作了一个支持以下内容的 C# 版本:
object b = 5;
ref object a = ref b;
b = 2;
// now a is 2
但这从未进入交付给客户的语言版本。
使一个变量别名为另一个变量的第二种方法仅适用于高级程序员;您可以创建一个指针,当取消引用时,该指针为变量添加别名:
int b = 5;
int* a = &b;
b = 2;
// Now *a is 2
请注意,指针类型只能像int
那样为"非托管类型"的变量提供别名,而不能像object
那样为托管类型提供别名。
我已经编写高级 C# 十年了,从来没有在生产代码中这样做过,所以如果我是你,我会避免它。
使一个变量别名成为另一个变量别名的第三种方法仅适用于高级程序员;可以使用 C# 的 TypedReference
类型和一些未记录的功能来捕获对变量的引用,然后稍后取消对别名的引用。我的建议是不要使用此功能。
using System;
class Program
{
static void Main(string[] args)
{
ValueTypeWrapper<int> a;
ValueTypeWrapper<int> b;
// The following line creates a new instance
// of ValueTypeWrapper<int> by the means of
// implicit conversion (see last method defined
// in the ValueTypeWrapper<T> class).
b = 5;
// Make the variable "a" point to the same
// ValueTypeWrapper<int> instance we just created.
a = b;
// Now that both variables are pointing to
// the same *instance*, change the value of
// the Value property.
b.Value = 2;
// Convert.ToString(...) will call
// ValueTypeWrapper<int>'s ToString()
// method, which in turn produces the
// string equivalent of the value inside
// the Value property.
// The Value property is equal to 2
// on both "a" and "b" objects as they
// point to the same instance.
Console.WriteLine(Convert.ToString(a));
Console.ReadLine();
}
}
public class ValueTypeWrapper<T> where T : struct
{
public T Value { get; set; }
public override string ToString()
{
return this.Value.ToString();
}
public static implicit operator ValueTypeWrapper<T>(T value)
{
return new ValueTypeWrapper<T> { Value = value };
}
}