为什么我不能在实例化后改变用作属性的结构中的字段?

时间:2011-03-25 04:24:30

标签: c# struct

我在C#中定义了如下结构(为了演示而简化),我在对本机DLL的互操作调用中使用它:

[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct MyStruct
{
    private byte val0;
    private byte val1;
    private byte val2;
    private byte val3;

    public MyStruct(UInt32 id)
    {
        this.val0 = (byte)id;
        id >>= 8;
        this.val1 = (byte)id;
        id >>= 8;
        this.val2 = (byte)id;
        id >>= 8;
        this.val3 = (byte)id;
    }

    public void Clear()
    {
        this.val0 = this.val1 = this.val2 = this.val3 = 0;
    }

    public override string ToString()
    {
        return
            this.val3.ToString("X2") + this.val2.ToString("X2") + "-" +
            this.val1.ToString("X2") + this.val0.ToString("X2");
    }
}

更新 此结构是另一个类中的属性。如下:

public class MyClass
{
    MyStruct MyStruct { get; set; }
}

当我使用值实例化结构并通过调用Clear()来执行此操作时,内容不会被清除。当我使用调试器进入Clear()方法时,我看到每个字段都被清除了。然而,一旦对Clear()的调用完成,原始结构实例将保持原始实例化值不变。

MyClass class1 = new MyClass();
class1.MyStruct = new MyStruct(0x12345678);
System.Diagnostics.Debug.WriteLine("Init: " + class1.MyStruct.ToString());
class1.MyStruct.Clear();
System.Diagnostics.Debug.WriteLine("Clear: " + class1.MyStruct.ToString());

以上结果如下:

  

Init:1234-5678
  清除:1234-5678

这是为什么?可以在实例化之后清除结构吗?

修改 示例代码和结果可在此处查看:http://ideone.com/6szn9

修改:修改问题以更准确地反映与属性访问者相关的问题。

2 个答案:

答案 0 :(得分:5)

对我不这样做。 http://ideone.com/PDLnt

您的真实代码是否有机会使用属性?属性getter在返回时会生成一个副本。

答案 1 :(得分:0)

您所看到的是物业运作方式的重大限制。如果要修改只能作为属性而不是字段访问的结构,则必须将结构读入临时变量,修改它并将其存储回来。有人会声称这是反对可变结构的论据。我认为虽然限制是不幸的,但代码如下:

  Rectangle tempRect = thing.Bounds;
  tempRect.X += 10;
  thing.Bounds = tempRect;

比Rectangle不是一个可变结构的东西更清晰,更自我解释。