Как вы, вероятно, можете догадаться, проблема в том, что оператор yield return
немного переписывает за кулисами, подобно тому, как это делает using
или лямбда-выражение. На самом деле он реализован как перечислитель, а код, который вызывает yield return
, является частью метода MoveNext
в перечислителе.
Это общая проблема использования Reflection: она дает вам время выполнения информацию о вашем исполняемом коде, которая может не соответствовать вашему времени компиляции представления о том, что это был за код. 1011 *
Это многословный способ сказать, что нет простого способа получить нужную информацию. Если бы вы переместили yield return
next в отдельный метод, то любой код вне этого метода не был бы частью MoveNext
, но это может или не может выполнить то, что вам нужно. Вы больше не получаете имя метода, выполняющего yield return
, вы получаете имя его вызывающего . Если это все, что вас волнует, это выглядит так:
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;
}
}
РЕДАКТИРОВАТЬ: Хотя я сомневаюсь, что это поможет вам в краткосрочной перспективе, для записи, эта проблема также решается при использовании новых атрибутов C # 5. Поскольку атрибут CallerMemberName
разрешается во время компиляции и, по-видимому, до того, как итератор был переписан в класс перечислителя, он создает имя свойства:
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;
}