C#索引器内存问题
我在main方法中有以下代码:C#索引器内存问题,c#,stack,heap,indexer,C#,Stack,Heap,Indexer,我在main方法中有以下代码: List<Rectangle> rects = new List<Rectangle>(); for (int i = 0; i < 5; i++) { rects.Add(new Rectangle(1, 1, 1, 1)); } foreach (Rectangle item in rects) { Console.WriteLine(item); } rects[1].Inflate(100, 100);
List<Rectangle> rects = new List<Rectangle>();
for (int i = 0; i < 5; i++)
{
rects.Add(new Rectangle(1, 1, 1, 1));
}
foreach (Rectangle item in rects)
{
Console.WriteLine(item);
}
rects[1].Inflate(100, 100);
foreach (Rectangle item in rects)
{
Console.WriteLine(item);
}
Program p = new Program();
p.rect[1].Inflate(100, 100);
foreach (var item in p.rect)
{
Console.WriteLine(item);
}
在主要方法中:
List<Rectangle> rects = new List<Rectangle>();
for (int i = 0; i < 5; i++)
{
rects.Add(new Rectangle(1, 1, 1, 1));
}
foreach (Rectangle item in rects)
{
Console.WriteLine(item);
}
rects[1].Inflate(100, 100);
foreach (Rectangle item in rects)
{
Console.WriteLine(item);
}
Program p = new Program();
p.rect[1].Inflate(100, 100);
foreach (var item in p.rect)
{
Console.WriteLine(item);
}
我希望rect数组的索引器也返回矩形结构的副本,但这次原始元素(也位于堆上)发生了更改
为什么呢?数组索引器的工作方式是否不同
问候
主键是。数组索引器表示要直接更改的变量。索引器基本上是一种带有索引参数的方法,并对其应用语法糖 相同的差异也适用于字段和属性
如果您从索引器返回一个引用类型,这不会有太大的区别,因为它引用的是同一个对象。但是,当您返回一个
结构
实例(或任何值类型)时,返回的值都会被复制,并且您试图修改副本,这几乎是无用的。据我所知,数组的“索引器”并不是真正的索引器。数组(或者更确切地说是数组类型)在.NET Framework中不能被视为普通类型,因为它具有特殊的角色。(再举一个例子,数组项是协变的,与其他类型相比,这在许多情况下有助于导致异常)。它只是引用数组的第n个元素,因此它返回的对象实际上是存储在数组中的实际对象。只需分别对待这两个概念。事实上,它们具有相同的语法在这里并不重要-功能上有一些相似之处,但不多。由此可以得出结论,列表上的索引器是一个方法调用,当从方法返回时,它将值类型的值放在堆栈上,数组索引器实际上在代码中转换为计算从数组开始的偏移量,并且是一个直接内存引用。如前所述,阵列在CLI中是特殊的东西。他们没有索引器。数组中的“索引”直接转换为相应的ldelem CIL指令。出于同样的原因,您不能执行类似于myWindowsForm.Location.X++代码>。说得好。如果您在示例中尝试{rects[1].X=100;}-不会编译,我相信,与{p.rect[1].X=100;}相反,它会编译并工作,那么您可以更清楚地看到相同的差异。