Questo è un caso di astrazione che perde. Una proprietà è in realtà un metodo, il get and set funzioni di accesso per un indicizzatore vengono compilate nei metodi get_Index () e set_Index. Il compilatore fa un ottimo lavoro nascondendo questo fatto, ad esempio traduce automaticamente un'assegnazione a una proprietà nel metodo set_Xxx () corrispondente.
Ma questo va a monte quando si passa un parametro del metodo per riferimento. Ciò richiede che il compilatore JIT passi un puntatore alla posizione di memoria dell'argomento passato. Il problema è che non ce n'è uno, l'assegnazione del valore di una proprietà richiede la chiamata del metodo setter. Il metodo chiamato non può dire la differenza tra una variabile passata e una proprietà passata e quindi non può sapere se è richiesta una chiamata al metodo.
Notevole è che questo funziona effettivamente in VB.NET. Per esempio:
Class Example
Public Property Prop As Integer
Public Sub Test(ByRef arg As Integer)
arg = 42
End Sub
Public Sub Run()
Test(Prop) '' No problem
End Sub
End Class
Il compilatore VB.NET risolve questo problema generando automaticamente questo codice per il metodo Run, espresso in C #:
int temp = Prop;
Test(ref temp);
Prop = temp;
Qual è la soluzione alternativa che puoi usare anche tu. Non sono sicuro del motivo per cui il team di C # non abbia utilizzato lo stesso approccio. Forse perché non volevano nascondere le chiamate getter e setter potenzialmente costose. O il comportamento completamente non diagnosticabile che otterrai quando il setter ha effetti collaterali che modificano il valore della proprietà, scompariranno dopo l'assegnazione. Differenza classica tra C # e VB.NET, C # è "nessuna sorpresa", VB.NET è "fallo funzionare se puoi".