Closed
Description
interface I1
{
public int P1 {get; set;}
}
class C1 : I1
{
public int F1;
public int P1
{
get
{
System.Console.Write(F1);
Program.F = new C1 { F1 = Program.F.F1 + 1 };
return 0;
}
set
{
System.Console.Write(F1);
}
}
}
class Program
{
public static C1 F = new C1 { F1 = 123 };
static void Main()
{
Test1(ref F);
System.Console.Write(F.F1);
System.Console.WriteLine();
System.Console.WriteLine("----------");
F = new C1 { F1 = 123 };
Test2(ref F);
System.Console.Write(F.F1);
}
static void Test1<T>(ref T f) where T : I1
{
f.P1++;
}
static void Test2(ref C1 f)
{
f.P1++;
}
}
Observed:
123124124
----------
123123124
Property setter prints "124" for generic scenario (it is the number in the middle of the first line in the output). Which means that getter and setter are executed on a different instances, but the receiver is supposed to be the same for both.
It is clear from IL why this is happening (the receiver is captured by reference and is used for constrained. calls):
.method private hidebysig static
void Test1<(I1) T> (
!!T& f
) cil managed
{
// Method begins at RVA 0x2128
// Code size 31 (0x1f)
.maxstack 3
.locals init (
[0] int32
)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: dup
IL_0003: constrained. !!T
IL_0009: callvirt instance int32 I1::get_P1()
IL_000e: stloc.0
IL_000f: ldloc.0
IL_0010: ldc.i4.1
IL_0011: add
IL_0012: constrained. !!T
IL_0018: callvirt instance void I1::set_P1(int32)
IL_001d: nop
IL_001e: ret
} // end of method Program::Test1
Expected:
123123124
----------
123123124