2011-09-02 73 views
9

可能重复:
Modify Struct variable in a Dictionary分配的领域/属性

为什么是它

MyStruct test = new MyStruct(); 
    test.Closed = true; 

伟大的作品,但

MyDictionary[key].Closed = true; 

在编译时显示“无法修改表达式,因为它不是变量”错误?

为什么在这两种情况下的分配有所不同?

注:MyDictionary类型为<int, MyStruct>

代码的结构:

public struct MyStruct 
{ 
    //Other variables 
    public bool Isclosed; 
    public bool Closed 
    { 
     get { return Isclosed; } 
     set { Isclosed = value; } 
    } 
//Constructors 
} 
+0

显示更多的代码.. – Zabba

+0

@Zabba,编辑更多的代码。 – soandos

+0

Downvoter评论请吗? – soandos

回答

12

因为MyDictionary[key]返回一个结构,它是真正返回对象的副本集合中,而不是实际的对象,当你使用一个类时会发生什么。这是编译器警告你的。

要解决这个问题,你必须重新设置MyDictionary[key],也许是这样的:

var tempObj = MyDictionary[key]; 
tempObj.Closed = true; 
MyDictionary[key] = tempObj; 
+0

但是,然后我需要再次调用整个构造函数没有?在这种情况下没有办法改变结构的一部分? – soandos

+0

我修改了我的示例以重用相同的对象,而不是创建一个新对象。 – Keith

+1

@soandos结构在方法之间传递时总是被复制,所以“整个构造函数”一直在发生(例如当你通过那个dict中的键访问你的结构时),这就是为什么它建议不要有大于16字节的结构 –

1

更改结构为一类,而不是...

class Program 
{ 
    static void Main(string[] args) 
    { 
     dic = new Dictionary<int, MyStruct>(); 

     MyStruct s = new MyStruct(){ Isclosed=false}; 

     dic.Add(1,s); 

     dic[1].Isclosed = true; 

     Console.WriteLine(dic[1].Isclosed.ToString()); //will print out true... 
     Console.Read(); 
    } 

    static Dictionary<int, MyStruct> dic; 

    public class MyStruct 
    { 
     public bool Isclosed; 
     public bool Closed 
     { 
      get { return Isclosed; } 
      set { Isclosed = value; } 
     } 
    } 
} 
+0

我知道结构在处理几个基本上包含像结构这样的字段的对象时效率更高,但如果碰巧只是实例化一些对象,那么创建一个类将为您节省一些代码:) –

+0

当使用暴露字段结构使用除数组之外的内置集合,必须复制该结构,对其进行修改,然后将其存回。麻烦,但语义是可以预测的; 'dic [1] .Isclosed'将总是独立于'dic [0] .Isclosed'。说'dic [0] = dic [1];'将复制'dic [0]'的状态而不附加两个项目在一起。如果使用可变类,可以写'dic [1] .Isclosed = true;'但这并不意味着这样做会产生所需的行为。一个将其状态封装在一个集合中的可变对象状态中的对象必须... – supercat

+0

...通常避免让任何对有问题的对象的引用到达外部代码。这意味着防御性地复制要存储在集合中的任何传入数据,并且防御性地复制或包装从其读取的任何数据。在读取或写入数据时,结构会自动执行防御性复制,但对任何大小的结构进行复制操作比在相同大小的类上进行复制操作要便宜得多。小结构的成本差异最大,但在结构变得非常大之前仍然很重要。 – supercat