gpt4 book ai didi

c# - 数组索引器和任何其他对象索引器有什么区别

转载 作者:太空狗 更新时间:2023-10-29 17:45:58 26 4
gpt4 key购买 nike

考虑以下两种数据类型:

class C
{
public int I { get; set; }
}

struct S
{
public int I { get; set; }
}

让我们尝试在列表中使用它们,例如:

var c_list = new List<C> { new C { I = 1 } };
c_list[0].I++;

var s_list = new List<S> { new S { I = 1 } };
s_list[0].I++; // (a) CS1612 compilation error

如预期的那样,(a) 行出现编译错误: CS1612 Cannot modify the return value of 'List<UserQuery.S>.this[int]' because it is not a variable .这很好,因为实际上我们试图修改 S 的临时副本,这是给定上下文中的 r 值。

但让我们尝试对数组做同样的事情:

var c_arr = new[] { new C { I = 1 } };
c_arr[0].I++;

var s_arr = new[] { new S { I = 1 } };
s_arr[0].I++; // (b)

而且..这行得通。

但是

var s_arr_list = (IList<S>) s_arr;
s_arr_list[0].I++;

不会像预期的那样编译。

如果我们查看生成的 IL,我们会发现以下内容:

IL_0057:  ldloc.1     // s_arr
IL_0058: ldc.i4.0 // index
IL_0059: ldelema UserQuery.S // manager pointer of element

ldelema将数组元素的地址加载到计算堆栈的顶部。 fixed 预期会出现这种行为数组和不安全指针。但是对于安全上下文来说,这有点出乎意料。为什么数组有一个特殊的不明显的情况?为什么没有为其他类型的成员实现相同行为的选项?

最佳答案

数组访问表达式被归类为变量。您可以分配给它,通过引用传递它等。索引器访问单独分类...在分类列表中(C# 5 规范第 7.1 节)

  • An indexer access. Every indexer access has an associated type, namely the element type of the indexer. Furthermore, an indexer access has an associated instance expression and an associated argument list. When an accessor (the get or set block) of an indexer access is invoked, the result of evaluating the instance expression becomes the instance represented by this (§7.6.7), and the result of evaluating the argument list becomes the parameter list of the invocation.

将此视为类似于字段和属性之间的区别:

 public class Test
{
public int PublicField;
public int PublicProperty { get; set; }
}

...

public void MethodCall(ref int x) { ... }

...

Test test = new Test();
MethodCall(ref test.PublicField); // Fine
MethodCall(ref test.PublicProperty); // Not fine

从根本上说,索引器是一对方法(或单个方法),而数组访问为您提供一个存储位置。

请注意,如果您一开始没有使用可变结构,您将看不出这种方式的区别——我强烈建议您根本不要使用可变结构。

关于c# - 数组索引器和任何其他对象索引器有什么区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31790651/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com