Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/274.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#索引器内存问题_C#_Stack_Heap_Indexer - Fatal编程技术网

C#索引器内存问题

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);

我在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);

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;}相反,它会编译并工作,那么您可以更清楚地看到相同的差异。