我有结构清单。我想修改结构中的特定数据。 结构位于List的特定索引位置。
我想做这样的事情:
struct sample
{
int a;
string name;
}
List<sample> list = new List<sample>();
for(int i=0; i < list.Count; i++)
{
list[i].a = someotherlist[i].data;
}
答案 0 :(得分:6)
问题是列表索引器会创建结构的副本,即它确实是:
for(int i=0; i < list.Count; i++)
{
var completelyIsolatedClone = list[i];
completelyIsolatedClone.a = someotherlist[i].data;
}
编译器阻止你犯了一个明显的错误。您使用的代码get
会改变数据的单独副本,但永远不会将其放回 - 因此您的更改不会做任何有用的事情。请注意,Mono人认为如果按照您的方式工作会很好:http://tirania.org/blog/archive/2012/Apr-11.html
请注意,数组的工作方式不同;你使用数组触摸结构到位,所以以下工作正常:
for(int i=0; i < list.Count; i++)
{
someArray[i].a = someotherlist[i].data;
}
另一种方法是将数据复制出来(get accessor),改变它并将其放回去:
for(int i=0; i < list.Count; i++)
{
var completelyIsolatedClone = list[i];
completelyIsolatedClone.a = someotherlist[i].data;
list[i] = completelyIsolatedClone;
}
或更好,完全禁用可变结构,可能使用将更改应用于新副本的方法:
for(int i=0; i < list.Count; i++)
{
list[i] = list[i].SetA(someotherlist[i].data);
}
其中SetA
创建 new 结构,例如DateTime.AddDays
等,即
public SomeType SetA(int a) {
return new SomeType(this.X, this.Y, a, this.Z);
}
答案 1 :(得分:2)
你不能这样做的原因是因为Sample是struct
,如果你把它改成一个类,那么你可以修改它。结构按值传递,也就是说,当方法返回结构时,将返回结构的副本,而不是原始结构。因此,当运行list[i].a = someotherlist[i].data;
时,您实际上正在修改副本,并且原始结构未被更改。编译器阻止你这样做,因为它可能不是你想要的。
您可以查看此帖子Why couldnot I modify the value of item from Generic Collections) ?
答案 2 :(得分:0)
我刚修改了我的代码,它对我来说很好用
public struct test
{
public int data;
public string name;
public int port_index;
}
static void Main(string[] args)
{
List<test> look_up = new List<test>();
test obj;
obj.data = 1;
obj.port_index = 0;
obj.name = "aaaa";
look_up.Add(obj);
test obj1;
obj1.data=3;
obj1.port_index=1;
obj1.name="sssss";
look_up.Add(obj1);
for(int i=0;i<look_up.Count;i++)
{
if (i == 1)
{
test temp = look_up[i];
temp.data = 5;
look_up[i] = temp;
}
}
}