Como es fácil adivinar, el problema aquí es que una declaración yield return
hace un poco de reescritura detrás las escenas, similar a cómo lo hace una expresión using
o lambda. En realidad se implementa como un enumerador, con el código que llama al yield return
como parte del método MoveNext
en el enumerador.
Este es un problema global de la utilización Reflexión: te da tiempo de ejecución información sobre su código de ejecución, que puede no coincidir con su tiempo de compilación idea de lo que era ese código.
Esa es una manera larga de decir que no hay una manera fácil de obtener la información que desea. Si fuera a mover el yield return
a otro método, entonces cualquier código que no pertenezca a ese método no formará parte del MoveNext
, pero puede que no logre lo que necesita. Ya no está obteniendo el nombre del método que está ejecutando el yield return
, recibe el nombre de la persona que llama. Si eso es todo lo que importa, que se ve así:
public IEnumerable<string> Something
{
get
{
var x = MethodBase.GetCurrentMethod().Name;
return this.DoSomething(x);
}
}
private IEnumerable<string> DoSomething(string x)
{
for (int i = 0; i < 5; i++)
{
yield return x;
}
}
EDIT: Aunque dudo que le ayudará en el corto plazo, para el registro, este problema también se resuelve al usar nuevos atributos de C# 5. Desde el atributo CallerMemberName
se resuelve en tiempo de compilación, y al parecer antes de que el iterador se ha reescrito en una clase de enumerador, se produce el nombre de la propiedad:
public IEnumerable<string> Something
{
get
{
var x = this.GetCallerName();
for (int i = 0; i < 5; i++)
{
yield return x;
}
}
}
private string GetCallerName([CallerMemberName] string caller = null)
{
return caller;
}
¿Cuál es el caso de uso? Si entendimos la necesidad y el contexto, probablemente podríamos ayudarlo mejor. – jason
¿Qué estás tratando de lograr? – Lloyd
@Jason, podría pensar en algunos casos de uso, solo uno de los cuales sería iniciar sesión. Es una buena pregunta – kelloti