Why does C# compiler generate error CS1612 for code that attempts to call indexer set accessor on immutable property?
using System;
using System.Collections.Generic;
using System.Text;
namespace StructIndexerSetter
{
struct IndexerImpl {
private TestClass parent;
public IndexerImpl(TestClass parent)
{
this.parent = parent;
}
public int this[int index]
{
get {
return parent.GetValue(index);
}
set {
parent.SetValue(index, value);
}
}
}
class TestClass
{
public IndexerImpl Item
{
get
{
return new IndexerImpl(this);
}
}
internal int GetValue(int index)
{
Console.WriteLine("GetValue({0})", index);
return index;
}
internal void SetValue(int index, int value)
{
Console.WriteLine("SetValue({0}, {1})", index, value);
}
}
class Program
{
static void Main(string[] args)
{
var testObj = new TestClass();
var v = testObj.Item[0];
// this workaround works as intended, ultimately calling "SetValue" on the testObj
var indexer = testObj.Item;
indexer[0] = 1;
// this produced the compiler error
// error CS1612: Cannot modify the return value of 'StructIndexerSetter.TestClass.Item' because it is not a variable
// note that this would not modify the value of the returned IndexerImpl instance, but call custom indexer set accessor instead
testObj.Item[0] = 1;
}
}
}
According to the documentation, this error means the following: "An attempt was made to modify a value type that is produced as the result of an intermediate expression but is not stored in a variable. This error can occur when you attempt to directly modify a struct in a generic collection, as shown in the following example:"
The error should not be produced in this case, since the actual value of the expression is not being modified. Note: Mono C# compiler handles the case as expected, successfully compiling the code.
list) { list[0].A = 42; } }`?– Jeppe Stig Nielsen Sep 06 '13 at 20:08