可以链接哪些变量类型?我试图使用对象,但它没有做我想做的事。可链接变量类型
object a;
object b;
b = 5;
a = b;
b = 2;
label1.Text = Convert.ToString(a);
它写出5,但我希望它是2.
可以链接哪些变量类型?我试图使用对象,但它没有做我想做的事。可链接变量类型
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
时,可以认为它是在纸b
上写下地址到家5
。当你说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
。
反复思考这个问题,直到你感觉它深入骨头。在你掌握这个基本概念之前,你会发现关于编程的推理非常具有挑战性。
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 };
}
}
谢谢您的回答 – halil12
没问题。我喜欢它作为纯粹的学术演习。您应该考虑将贾森的帖子标记为答案,但是,他已经花了一些时间来解释价值和参考类型之间的差异 - 您应该仔细阅读并尝试吸收。 –
如果你只是稍微描述一下这个概念,那就太好了。 –
杰森的回答很好;更添加到它:
你似乎期望,当你说a = b
,这意味着a
和b
和现在相同的变量的别名。这不是什么意思; a = b
表示将存储位置b
的内容复制到存储位置a
而不是重新标记存储位置a
。
There is然而一种使两个变量相互混淆的方法;实际上有三种方法可以在C#中完成这三种方式(除了杰森建议的技术之外,这可能是最好的)。
第一种方式是使用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#十年,并且从来没有在生产代码中这样做过,所以如果我是你,我会避免它。
使另一个变量别名的第三种方法是仅适用于高级程序员;您可以使用TypedReference
类型和C#的一些未公开的功能来捕获对变量的引用,然后再取消引用别名。我的建议是不使用此功能。
我想问一个问题。我可以发送一个数组的元素作为参考? – halil12
@ halil12:是; *任何*变量都可以通过'ref'传递。数组元素是一个变量。你不能通过ref的一件事是*属性*;具有getter和setter的属性实际上并不是一个变量。 –
首先阅读MSDN上的[值类型和引用类型](http://msdn.microsoft.com/en-us/library/t63sy5hs.aspx)。 – Oded
[拳击和拆箱](http://msdn.microsoft.com/en-us/library/yz2be5wk.aspx)将是一个很好的第二页来通读。 – Oded
in [值类型和引用类型](http://msdn.microsoft.com/en-us/library/t63sy5hs.aspx)它说“引用类型如Object”,so是object是引用类型还是不是? – halil12