在这里讨论了SO之后,我已经多次读过可变结构是"邪恶"的评论(就像这个问题的答案一样).
C#中可变性和结构的实际问题是什么?
我正在使用自动实现的属性.我想解决以下问题的最快方法是声明我自己的支持变量?
public Point Origin { get; set; }
Origin.X = 10; // fails with CS1612
Run Code Online (Sandbox Code Playgroud)
错误消息:无法修改'expression'的返回值,因为它不是变量
尝试修改作为中间表达式结果的值类型.由于该值未持久存在,因此该值将保持不变.
要解决此错误,请将表达式的结果存储在中间值中,或使用中间表达式的引用类型.
我有这个结构:
struct Map
{
public int Size;
public Map ( int size )
{
this.Size = size;
}
public override string ToString ( )
{
return String.Format ( "Size: {0}", this.Size );
}
}
Run Code Online (Sandbox Code Playgroud)
使用数组时,它可以工作:
Map [ ] arr = new Map [ 4 ] {
new Map(10),
new Map(20),
new Map(30),
new Map(40)};
arr [ 2 ].Size = 0;
Run Code Online (Sandbox Code Playgroud)
但是当使用List时,它不会编译:
List<Map> list = new List<Map> ( ) {
new Map(10),
new Map(20),
new Map(30),
new Map(40)};
list [ 2 …Run Code Online (Sandbox Code Playgroud) 当我使用一个structs 数组(例如System.Drawing.Point)时,我可以逐个索引并更改它.
例如(此代码工作正常):
Point[] points = new Point[] { new Point(0,0), new Point(1,1), new Point(2,2) };
for (int i = 0; i < points.Length; i++)
{
points[i].X += 1;
}
Run Code Online (Sandbox Code Playgroud)
但是当我使用List时,它不起作用:
无法修改'System.Collections.Generic.List.this [int]'的返回值,因为它不是变量
示例(此代码无法正常工作):
List<Point> points = new List<Point> { new Point(0,0), new Point(1,1), new Point(2,2) };
for (int i = 0; i < points.Count; i++)
{
points[i].X += 1;
}
Run Code Online (Sandbox Code Playgroud)
我知道当我通过索引获取列表项时,我得到了它的副本和编译器提示我没有提交错误,但为什么采用数组索引的元素工作方式不同?
我正在尝试理解/调和我对使用List和Arrays进行链接时C#结构如何运作的理解.我在本文的结构类型数组的性能中遵循了Eric的解释
但我更进一步.
struct Foo { public int A; public int B; public Foo[] ChildFoos; }
Foo parentFoo = new Foo();
parentFoo.ChildFoos = new Foo[1];
parentFoo.ChildFoos[0] = new Foo();
List<Foo> list = new List<Foo>();
list.Add(parentFoo);
Run Code Online (Sandbox Code Playgroud)
但是当您链接呼叫时,行为会发生变化.list [0]应该返回一个值(不是变量),其中ChildFoos [0]应该返回一个变量.
list[0].ChildFoos[0].A = 4545;
Run Code Online (Sandbox Code Playgroud)
在这种情况下,似乎正在发生的事情是list [0]被视为变量而不是值.ChildFoos [0] .A在List中的parentFoo中维护它的新值.这怎么可能?
将此与尝试在不能编译的父Foo结构上设置A进行比较.
list[0].A = 877;
Run Code Online (Sandbox Code Playgroud)
这不会编译
好的,我有一个List<SpecialTile>叫做SpecialTileswhere SpecialTile的结构.SpecialTile结构的一个属性是一个名为Active我正在尝试更改的公共布尔值,但由于某种原因它不起作用.我不确定它是否相关,但列表由另一个类的实例拥有.这是我在调试器中运行时的图片:

所以无论如何,我遇到了这个问题,因为最初我试图使用代码行
Mgen.SpecialTiles[ESV.editThis].Active = !Mgen.SpecialTiles[ESV.editThis].Active;
Run Code Online (Sandbox Code Playgroud)
但它告诉我"活跃"并非变数.正如你所看到的,它不会让我以这种方式修改价值:

所以我假设我必须通过方法修改值.但显然这也不起作用?
我错过了List变量的一些内容吗?即使它不应该修改该值,为什么调试器列出"Active"为false然后将其翻转为true?
谢谢!
C#不允许我这样做.
foreach (Point point in filledPoints)
{
point.X = 0;
}
Run Code Online (Sandbox Code Playgroud)
filledPoints是一个List<Point>
它给了我一个编译器错误:"filledPoints是一个foreach迭代变量,因此无法编辑关联的成员"(对不起,该消息是德语,我很难翻译).但这有效:
foreach (Point point in filledPoints)
{
Point point2 = point;
point2.X = point2.X / oldSize.Width * Size.Width;
}
Run Code Online (Sandbox Code Playgroud)
为什么这不起作用,是否有更优雅的方式绕过它?