给定
SomeStruct s1, s2, s3;
Object o1;
... s1 gets a value somehow, then...
s2 = s1; // Q1
o1 = s1; // Q2
s3 = (SomeStruct)o1; // Q3
语句 Q1 将s2
通过使用s1
. 语句 Q2 将生成一个新的堆对象,该对象的行为就好像它包含一个类型为 的字段SomeStruct
,并将通过用 中的相应字段覆盖其所有字段来修改该字段s1
。语句 Q3 将检查是否o1
包含“装箱” SomeStruct
,如果是,将用s3
装箱对象中的相应字段覆盖 的所有字段。
请注意,盒装结构通常不会在它们位于堆对象中时被修改。如果有人说:
var temp = (SomeStruct)o1;
temp.someField = Whatever;
o1 = temp;
该序列将创建一个新的堆对象,该对象将保存原始结构的修改副本,但原始盒装结构将保持原样。但是,有一些方法可以修改装箱对象中的结构。在大多数情况下应该避免使用这种技术,但应该知道不存在非平凡的不可变结构(没有字段的结构是不可变的,但不是很有用)。一般来说,如果希望能够引用结构类型的可变实例,最好将它封装在一个简单的类对象中,例如
class ExposedFieldHolder<T>
{
public T Value;
public ExposedFieldHolder(T v) {Value = v;}
}
如果想要一个不可变的实例,应该将它封装在一个不可变的类对象中
class ImmutableHolder<T>
{
T value;
public T Value { get { return value; } ;
public ImmutableHolder(T v) {value = v;}
override public bool Equals(Object o) {
var other = o as ImmutableHolder<T>;
if (!other) return false;
return Object.Equals(value,other.value);
}
override public int GetHashCode() { return Object.GetHashCode(value); }
}