using System;
using System.Collections.Generic;
class C
{
static void Main()
{
foreach (var func in new C().Foo())
{
Console.WriteLine(func.Method.Name);
}
}
IEnumerable<Func<string>> Foo()
{
yield return base.ToString;
}
}
Ф>каков смысл у этого этюда?
nikov тогда бы сюда не запостил
как насчет запустить? результат очень странный. поиск в гугле, от чего именно так, пока ничего не дал.
Поэкспериментировал с VS, всегда выдает один и тот же результат — дебаговое(?), неверное имя.
Но при компиляции с консоли выдает предупреждение, и код генерирует верный.
Магия какая-то.
Народ называет это "undocumented implementation details of the compiler" и "VS debugger 'magic names'".
Ф>студия тоже выдаёт предупреждение — это ничего не значит. Ф>каков "верный код"?
В VS 2010 выдает "<>n__FabricatedMethod1", при компиляции никаких предупреждений.
Здравствуйте, namespace, Вы писали:
Ф>>студия тоже выдаёт предупреждение — это ничего не значит. Ф>>каков "верный код"? N>В VS 2010 выдает "<>n__FabricatedMethod1", при компиляции никаких предупреждений.
похоже на баг компилятора
Всё сказанное выше — личное мнение, если не указано обратное.
Здравствуйте, Философ, Вы писали:
Ф>Здравствуйте, namespace, Вы писали:
Ф>>>студия тоже выдаёт предупреждение — это ничего не значит. Ф>>>каков "верный код"? N>>В VS 2010 выдает "<>n__FabricatedMethod1", при компиляции никаких предупреждений.
Ф>похоже на баг компилятора
А если поменять base на this?
Тут все понятно на самом деле, любая лямда — это сгенерированный компилятором класс с полями из захваченных переменных и методом с телом лямды.
Для досткпаю к this сгенерированный класс просто захватывает переменную this. Для base он так поступить не может, потому что ToString виртуальный метод. Т.е. захват для base не работает и компилятор не зря по этому поводу ругается.
Я в таких случаях создаю отдельный метод который стучится к base.
В общем нужно в ILDasm запускать и смотреть куда добавился сгенерированный метод FactoryMethod.
У меня компа под рукой нет, кто может заглянуть?
Думаю разные результаты под студией и под консолью потому что метод ToString не переопределен в наследнике и компилятор может прекрасно понять что вместо base.ToString стоит использовать this.ToString. В случае дебага под студией он такую оптимизацию не проводит.
То, что сгенерирован класс с методом — понятно.
Ненормально то, что если вызвать тот метод "n__FabricatedMethod1" над нашим объектом класса С, то выполнится код из base(в VS 2010).
Так же склоняюсь к мысли, что это баг.
using System;
using System.Collections.Generic;
class C : A
{
static void Main()
{
new D().Run();
Console.Read();
}
public IEnumerable<Func<string>> Foo()
{
yield return base.MyToString;
}
public Func<string> GetMyToString()
{
return base.MyToString;
}
public override string MyToString()
{
return"Overrided MyToString";
}
}
class A
{
public virtual string MyToString()
{
return"Virtual MyToString";
}
}
class D
{
public void Run()
{
C c = new C();
foreach (var func in c.Foo())
{
Console.WriteLine(func.Method.Invoke(c, null));//Virtual MyToString либо Overrided MyToString
}
Console.WriteLine(c.GetMyToString().Method.Invoke(c, null));//Overrided MyToString
}
}