哪些变量类型可以链接?我试图使用对象,但它没有做我想要的。
object a;
object b;
b = 5;
a = b;
b = 2;
label1.Text = Convert.ToString(a);
它写了5但我希望它是2。
答案 0 :(得分:7)
这是对引用及其工作方式的简单误解,以及变量是什么。
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
。
一遍又一遍地思考这个问题,直到你感觉到它深藏在你的骨头里。在你掌握这个基本概念之前,你会发现编程的理由非常具有挑战性。
答案 1 :(得分:5)
当您说a = b
这意味着a
和b
现在是同一个变量的别名时,您似乎期望。这不是它的意思; a = b
表示将存储位置b
的内容复制到存储位置a
,而不是 relabel 存储位置{{1} }。
然而 是一种让两个变量互为别名的方法;事实上,在C#中有三种方式(除了Jason建议的技术,这可能是最好的)。
第一种方法是使用a
和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
也是因为它们是具有两个不同名称的相同变量。
但是在单个方法中没有办法。底层运行时支持这一点,我曾经制作过支持的C#版本:
a
但这从未成为发给客户的语言版本。
将一个变量别名变为另一个变量的第二种方法仅适用于高级程序员;你可以制作一个指针,当取消引用别名变量时:
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
那样使用托管类型。
我已经编写了十年的高级C#并且从未在生产代码中执行此操作,所以如果我是你,我会避免使用它。
将一个变量别名变为另一个变量的第三种方法仅适用于高级程序员;您可以使用object
类型和C#的一些未记录的功能来捕获对变量的引用,然后再解除引用到别名中。我的建议是不要使用此功能。
答案 2 :(得分:0)
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 };
}
}