【问题标题】:What are Array Indexes?什么是数组索引?
【发布时间】:2016-11-04 00:21:21
【问题描述】:

例如,我知道List<T> 索引器类似于属性。取自msdn:

索引器允许类或结构的实例被索引就像 数组。索引器类似于属性,只是它们的访问器采用 参数。

但我不明白为什么会发生以下情况:

int[] myArray = new int[0];
List<int> myList = new List<int>();

Interlocked.Increment(ref myArray[0]);  // fine

Interlocked.Increment(ref myList[0]);   //CS0206    A property or indexer may not be passed as an out or ref parameter

他们不应该以同样的方式工作吗?

【问题讨论】:

  • 请检查 Mike Chamberlain 对重复问题的回答。尽管它没有被标记为正确答案是更详细的答案,但它确实清楚地解释了为什么这是不可能的。希望对您有所帮助。
  • @Christos Imo 它没有回答问题
  • @Christos 我不是在问这个错误。
  • @Christos 我同意 Zbigniew。真正的问题是为什么它适用于数组,而不是为什么它不适用于列表索引器。
  • 因为数组是特殊的。

标签: c# arrays indexing


【解决方案1】:

List&lt;T&gt; 的索引器允许您使用属性(方法)访问元素,使其看起来像一个数组。你不能像你写的那样通过ref传递生成的方法:

Interlocked.Increment(ref myList.GetItem.get_Item(0));

但是访问数组的元素不是通过索引器。 CLR 直接支持访问数组元素。所以array[i]返回一个变量,ref可以传递。

来自 C# 规范:

即使访问索引器元素的语法与 对于数组元素,索引器元素不属于 多变的。因此,不可能将索引器元素作为 ref 传递 或出论点。

这是List&lt;T&gt;(内部使用数组)的索引器:

public T this[int index]
{
    get
    { // some checks removed 
        return _items[index];
    }

    set { _items[index] = value;}
}

从 IL 一侧:

访问数组元素会生成这条直接 IL 指令:

IL_0014: ldelem.i4

通过索引器访问列表的元素会生成:

IL_001b:  callvirt   instance !0 class [mscorlib]System.Collections.Generic.List`1<int32>::get_Item(int32)

所以,它是相同的 c# 语法。但是生成的IL就完全不一样了。

【讨论】:

  • “尽管访问索引器元素的语法与访问数组元素的语法相同,但索引器元素不属于变量。”。正是我想阅读的内容:数组中的索引返回变量本身。
【解决方案2】:

这是因为索引器是属性,而属性最终是函数。因为它们是函数,所以它们不会(必要)像数组索引那样引用内存中的特定位置。如果语言 DID 允许,开发人员将能够轻松地破坏引用和语义,它就无法正常工作。举个例子:

public class Foo {
        public int this[int x] {
            get {
                return 1;
            }
            set {
                //meh. whatever. 
            }
        }
    }

如果我将Foo[0] 作为输出参数传递,刚刚发生了什么?在这种情况下,我什至没有设置任何东西。这完全打破了refout 的语义。

【讨论】:

  • 打败我吧,虽然我会在这里引用第 174 行...referencesource.microsoft.com/#mscorlib/system/collections/…
  • '索引器是属性,属性最终是函数'。使用相同的逻辑,数组索引也是属性,最终也是函数,但它们的作用不同,正如您在问题示例中看到的那样。
  • 不,索引和索引器是两个不同的东西。
猜你喜欢
  • 2021-08-04
  • 2014-10-13
  • 1970-01-01
  • 2021-03-29
  • 1970-01-01
  • 2020-05-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多