我试过了:
int i = 5;
object o1 = i; // boxing the i into object (so it should be a reference type)
object o2 = o1; // set object reference o2 to o1 (so o1 and o2 point to same place at the heap)
o2 = 8; // put 8 to at the place at the heap where o2 points
运行此代码后,o1中的值仍为5,但我预计为8.
我错过了什么吗?
答案 0 :(得分:14)
这不是C#中变量的工作方式。它与拳击值类型无关。
考虑一下:
object o1 = new object();
object o2 = o1;
o2 = new object();
为什么您希望o1
和o2
包含对同一对象的引用?设置o2 = o1
时它们是相同的,但是一旦设置o2 = new object()
,o2
的值(变量指向的内存位置)就会发生变化。
也许您正在尝试做的事情可以这样做:
class Obj {
public int Val;
}
void Main() {
Obj o1 = new Obj();
o1.Val = 5;
Obj o2 = o1;
o2.Val = 8;
}
在Main
结束时,Val
的{{1}}属性将包含o1
。
答案 1 :(得分:4)
要执行您想要执行的操作,该值必须是引用类型的属性:
public class IntWrapper
{
public int Value { get; set; }
public IntWrapper(int value) { Value = value; }
}
IntWrapper o1 = new IntWrapper(5);
IntWrapper o2 = o1;
o2.Value = 8;
答案 2 :(得分:1)
@Ken为您提供完美的答案。这个是如何使用struct
(值类型)获得相同的行为。
注意:可变值类型的行为非常不直观,请勿在家中尝试:)。
要获得与值类型类似的行为,您需要通过接口实现一些接口和设置属性,因为取消装箱struct
到它自己的类型将始终创建副本,您将无法修改原始值。
void TortureMutableBoxedValueType()
{
object o1 = new IntWrapper(5);
object o2 = o1;
Console.WriteLine(((IValue)o1).Value); // outputs original 5
((IValue)o2).Value = 8;
Console.WriteLine(((IValue)o1).Value); // outputs new 8
}
interface IValue
{
int Value {get;set;}
}
// Don't use mutable value types - this is just sample.
public struct IntWrapper : IValue
{
int v;
public int Value { get { return v;} set {v = value;}}
public IntWrapper(int value) { v = value; }
}
答案 3 :(得分:0)
正如Joel指出的那样,即使盒装它仍然是一个值类型,因此它没有被引用它被克隆。这就是你看到这个结果的原因 - o1和o2指向不同的内存位置。
答案 4 :(得分:-1)
也许不相关,但是如果您正在寻找一个整数来用作引用类型(例如,在某种方法中传递变量并对其进行一些操作并在退出方法后保留值),则可以使用ref关键字。像这样:
<max:WORKORDER>
<max:SITEID>BEDFORD</max:SITEID>
<max:CLASSSTRUCTUREID>1001</max:CLASSSTRUCTUREID>
<max:WORKORDERSPEC>
<max:ALNVALUE>123</max:ALNVALUE>
<max:ASSETATTRID>TESTATTR</max:ASSETATTRID>
</max:WORKORDERSPEC>
</max:WORKORDER>
方法如下:
int index = 0;
SomeMethod(ref index);