无法在循环中修改struct的对象

时间:2010-01-28 03:54:41

标签: c# collections

我有一个结构列表。在循环中我试图修改对象的属性,这正在发生,但当我(快速查看Visual Studio)查看列表对象时,新值没有反映.Is它是因为在集合中结构的对象不能被修改? 我使用泛型列表,结构作为列表中的类型

4 个答案:

答案 0 :(得分:2)

您在结构的上下文中提到“修改对象的属性”,但重要的是结构不是对象。其他人已经回答了结构被复制的问题(以及丢弃的更改),但是为了进一步解决真正的问题,你一个可变的(可变的) struct at all 。除非您使用XNA(或类似版本),否则根本不需要。

如果您希望能够更改属性,请将其设为类:

public class Foo {
    public string Bar {get;set;}
}

现在这是一个引用类型,您的更改(obj.Bar = "abc";)将通过foreach保留。如果你真的想/需要一个结构,那就让它变成不可变的:

public struct Foo {
    private readonly string bar;
    public string Bar { get {return bar; }}
    public Foo(string bar) {this.bar = bar;}
}

现在你无法犯错误更改副本的价值;您将不得不使用索引器交换值(list[i] = new Foo("abc");)。更详细(您不能使用foreach),但更正。

但IMO,使用一个班级。说实话,结构非常罕见。如果你不确定:上课。

答案 1 :(得分:1)

如果您使用的是foreach循环,则可能

Compiler Error CS1654

  

错误消息无法修改成员   '变量',因为它是'只读'   变量类型'

     

尝试时会发生此错误   修改变量的成员   只读,因为它是特殊的   构造

     

发生这种情况的一个常见领域是   在foreach循环中。它是一个   编译时错误修改值   的集合元素。因此,   你不能做任何修改   作为价值类型的元素,   包括结构。

但你可以尝试

struct MyStruct
{
    public int i;
}

List<MyStruct> list = new List<MyStruct> 
        { new MyStruct { i = 1 }, new MyStruct { i = 2 } };

for(int i = 0; i < list.Count; i++)
{
    MyStruct val = list[i];
    val.i++;
    list[i] = val;
}

修改

另见Structs Tutorial

结构与类

  

结构似乎与类相似,   但是有重要的区别   你应该知道的。首先   所有,类都是引用类型和   结构是价值类型。

答案 2 :(得分:1)

我认为我知道问题可能是什么。

struct Astruct
{
   int amember;
}

List < Astruct > listofStructs;

foreach(Astruct A in listofStructs)
{
     A.amember = 1337;
}

如果这是你正在做的......

当你在c#中使用结构时,它们不会被引用但是被复制了!这意味着列表的内容正在被复制到A,所以当你改变A时它不会改变列表中的值!

解决这个问题(如果这是你的问题...)要么使用CLASSES而不是STRUCTS,那么A将是一个引用,或者使用手动迭代for循环,即:

for(int i=0;i < listofStructs.Count;i++)
{
    listofStructs[i].amember = 1337;
}

或者,如果您正在使用列表,您可能应该使用迭代器或其他东西......但上述内容肯定能解决这个问题。

答案 3 :(得分:0)

鉴于你帖子中的信息(尽管我希望看到代码本身),让我提出最可能的问题及其解决方法。

   foreach(var s in listOfStructs)
    {
      s.Property = x;
    }

被分配给集合中实际结构的副本。 s.set_Property现在正在修改在当前迭代结束时丢弃的副本。

这是因为2个值类型变量不能指向同一个实例。

struct1 = new MyStruct(100, 200);
struct2 = struct1;   // struct2 is now a copy of struct1

现在讨论如何修改集合中的实例的问题:
获取要在局部变量中修改的对象(创建副本)。修改它。现在删除原始对象并插入副本。使用listOfStructs[i] = modifiedInstance