A property or indexer may not be passed as an out or ref parameter
Hoy, mi compañero de trabajo y yo estabamos dándole vueltas al por qué de este error en el compilador de C# y no en el de VB.NET. Mirando una buena explicación del por qué el compilador de C# no permite esto, he encontrado esta:
a.cs
class zzz
{ public static void Main()
{ yyy a = new yyy();
a.aa = 10;
a.abc(ref a.aa);
}
}
class yyy
{ public int aa
{ get { return 0; } set { } }
public void abc(ref int b)
{
}
}
Compiler Error
a.cs(7,11): error CS0206: A property or indexer may not be passed as an out or ref parameter
If it walks like a duck, quacks like a duck, it's a duck. A property looks and feels like a variable but it is actually a series of functions or to be technically correct, accessors. Only a storage or memory location can be passed as a ref or an out parameter. A property is not allocated any memory and thus cannot be used wherever a variable can be used. All the restrictions of static apply to static properties too. The get accessor must terminate either in a return or a throw statement. Control cannot flow off the accessor body at the end. A set accessor is like a function that returns void and it has an implicit parameter value.
fuente original: http://www.vijaymukhi.com/documents/books/csadv/chap1.htm
Pero me picaba la curiosidad y he querido ver como lo trata el compilador de VB.NET (Que era la solución que pensabamos para C#):
Module Module1
Sub Main()
Dim a As New yyy()
a.aa = 10
yyy.abc(a.aa)
End Sub
End Module
Class yyy
Private _codigo As Integer
Public Property aa() As Integer
Get
Return 0
End Get
Set(ByVal value As Integer)
_codigo = value
End Set
End Property
Public Shared Sub abc(ByRef b As Integer)
End Sub
End Class
Visto con Reflector:
[STAThread]
public static void Main()
{ yyy a = new yyy();
a.aa = 10;
yyy VB$t_ref$S0 = a;
int VB$t_i4$S0 = VB$t_ref$S0.aa;
yyy.abc(ref VB$t_i4$S0);
VB$t_ref$S0.aa = VB$t_i4$S0;
}
Lo hace con una variable auxiliar del tipo de la propiedad :)
Cuanto menos curioso, ¿No?
Salu2