赋值的左侧必须是变量、属性或索引器

Posted

技术标签:

【中文标题】赋值的左侧必须是变量、属性或索引器【英文标题】:The left-hand side of an assignment must be a variable, property or indexer 【发布时间】:2015-07-07 13:46:53 【问题描述】:

我遇到了一个错误,我不知道为什么:

static void decoupeTableau(IEnumerable<int> dst, IEnumerable<int> src)

    for (int i = 0; i < src.Count() && i < 4; ++i)
        dst.ElementAt(i) = src.ElementAt(i); // Here

错误:

为什么我会得到它?

【问题讨论】:

dst.ElementAt(i) 将返回一个值,例如数字 42,然后您尝试为其分配一些新值。加看***.com/questions/5595955/… 我想你想要的这个方法之外是dst = src.Take(4).Concat(dst.Skip(Math.Min(4, src.Count()))); 错误说明了问题所在。 【参考方案1】:

为什么我会得到它?

因为你有一个赋值运算符,左边是一个方法调用。你期望它做什么?那会调用什么代码?赋值必须要么设置变量的值,要么调用属性的设置器。这并没有做这两件事。

基本上,你不能这样做 - 对于IEnumerable&lt;T&gt;,它甚至没有意义,因为它可以是只读的、生成的等等。

也许你想要一个 IList&lt;int&gt; 代替:

static void DecoupeTableau(IList<int> dst, IEnumerable<int> src)
 
    int i = 0;
    foreach (var value in src.Take(4))
    
        dst[i] = value;
        i++;
    

请注意,此代码也可能大大更有效率 - 在循环中调用 Count()ElementAt 可能非常昂贵。 (例如,使用生成器,每次调用 Count() 时,您都必须遍历 整个 流 - 所以如果这是理论上无限的流,它甚至不会完成,例如随机整数序列。)

【讨论】:

“因为你有一个赋值运算符,左边是一个方法调用” - 为什么当方法返回一个对象时会出现问题? @Sipo:我不知道你为什么认为它不会是个问题。方法调用的结果是一个值,而不是一个变量。你不能分配一个值——这甚至意味着什么?可能相关:该方法不返回对象。它返回一个引用。没有任何东西会返回一个实际的对象。每个归类为值的表达式要么是值类型值,要么是引用(或指针)。 如果它返回一个引用,Method() = new Something() 不是意味着这个引用现在引用了一个不同的对象吗? @Sipo:我还不清楚你希望它做什么。 哪个引用现在指向不同的对象?您是否建议如果我从方法返回私有字段的值(例如 string 引用),调用者应该能够更改我的字段的值以引用不同的字符串?绝对不是…… 我相信我现在明白了这个问题。谢谢!【参考方案2】:

IEnumerable 的特点是您可以遍历项目但不能更改列表。如果您需要实际更改列表,则需要 IList 或数组或类似的。

您得到的错误是因为 ElemetAt 是一个函数,而不是元素本身。

另外,使用 for 循环遍历 IEnumerable 也是一个特别糟糕的主意,您需要一个 foreach 循环来代替。

【讨论】:

以上是关于赋值的左侧必须是变量、属性或索引器的主要内容,如果未能解决你的问题,请参考以下文章

C# 错误中的左侧赋值

学习系列之索引器与属性

C#索引器

C#索引器

C# 笔记——索引器

C#004.索引器事件结构集合委托