[C#, Этюд] base.ToString
От: nikov США http://www.linkedin.com/in/nikov
Дата: 14.04.12 01:51
Оценка: +1
Что напечатает эта программа?

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;
    }
}
Re: [C#, Этюд] base.ToString
От: Философ Ад http://vk.com/id10256428
Дата: 14.04.12 04:37
Оценка:
Здравствуйте, nikov, Вы писали:

N>Что напечатает эта программа?


по-моему это очевидно: "ToString" она напечатает.

об этом однозначно говорит строка
yield return base.ToString


каков смысл у этого этюда?
какие могут быть варианты ответов, кроме того, который я привёл?
Всё сказанное выше — личное мнение, если не указано обратное.
Re[2]: [C#, Этюд] base.ToString
От: namespace  
Дата: 14.04.12 04:42
Оценка:
Ф>каков смысл у этого этюда?
nikov тогда бы сюда не запостил
как насчет запустить? результат очень странный. поиск в гугле, от чего именно так, пока ничего не дал.
Re[3]: [C#, Этюд] base.ToString
От: Философ Ад http://vk.com/id10256428
Дата: 14.04.12 04:49
Оценка:
Здравствуйте, namespace, Вы писали:

N>как насчет запустить? результат очень странный.


запустил.
результат именно такой, как я сказал.
Всё сказанное выше — личное мнение, если не указано обратное.
Re[4]: [C#, Этюд] base.ToString
От: namespace  
Дата: 14.04.12 05:42
Оценка:
Поэкспериментировал с VS, всегда выдает один и тот же результат — дебаговое(?), неверное имя.
Но при компиляции с консоли выдает предупреждение, и код генерирует верный.
Магия какая-то.

Народ называет это "undocumented implementation details of the compiler" и "VS debugger 'magic names'".
Re[5]: [C#, Этюд] base.ToString
От: Философ Ад http://vk.com/id10256428
Дата: 14.04.12 05:46
Оценка:
Здравствуйте, namespace, Вы писали:

N>Но при компиляции с консоли выдает предупреждение, и код генерирует верный.


студия тоже выдаёт предупреждение — это ничего не значит.
каков "верный код"?
Всё сказанное выше — личное мнение, если не указано обратное.
Re[6]: [C#, Этюд] base.ToString
От: namespace  
Дата: 14.04.12 05:50
Оценка:
Ф>студия тоже выдаёт предупреждение — это ничего не значит.
Ф>каков "верный код"?
В VS 2010 выдает "<>n__FabricatedMethod1", при компиляции никаких предупреждений.
Re[7]: [C#, Этюд] base.ToString
От: Философ Ад http://vk.com/id10256428
Дата: 14.04.12 06:02
Оценка:
Здравствуйте, namespace, Вы писали:

Ф>>студия тоже выдаёт предупреждение — это ничего не значит.

Ф>>каков "верный код"?
N>В VS 2010 выдает "<>n__FabricatedMethod1", при компиляции никаких предупреждений.

похоже на баг компилятора
Всё сказанное выше — личное мнение, если не указано обратное.
Re[8]: [C#, Этюд] base.ToString
От: _WerWolf_  
Дата: 14.04.12 06:58
Оценка:
Здравствуйте, Философ, Вы писали:

Ф>Здравствуйте, namespace, Вы писали:


Ф>>>студия тоже выдаёт предупреждение — это ничего не значит.

Ф>>>каков "верный код"?
N>>В VS 2010 выдает "<>n__FabricatedMethod1", при компиляции никаких предупреждений.

Ф>похоже на баг компилятора


А если поменять base на this?

Тут все понятно на самом деле, любая лямда — это сгенерированный компилятором класс с полями из захваченных переменных и методом с телом лямды.
Для досткпаю к this сгенерированный класс просто захватывает переменную this. Для base он так поступить не может, потому что ToString виртуальный метод. Т.е. захват для base не работает и компилятор не зря по этому поводу ругается.
Я в таких случаях создаю отдельный метод который стучится к base.

В общем нужно в ILDasm запускать и смотреть куда добавился сгенерированный метод FactoryMethod.
У меня компа под рукой нет, кто может заглянуть?
Re[9]: [C#, Этюд] base.ToString
От: _WerWolf_  
Дата: 14.04.12 07:02
Оценка:
Забыл добавитт.

Думаю разные результаты под студией и под консолью потому что метод ToString не переопределен в наследнике и компилятор может прекрасно понять что вместо base.ToString стоит использовать this.ToString. В случае дебага под студией он такую оптимизацию не проводит.
Re[10]: [C#, Этюд] base.ToString
От: Философ Ад http://vk.com/id10256428
Дата: 14.04.12 07:34
Оценка:
Здравствуйте, _WerWolf_, Вы писали:

_WW>base.ToString стоит использовать this.ToString


Тем не менее речь всё же идёт о методе ToString, и именно его я ожидаю увидеть в консоли.
в принципе всё равно чей метод будет захвачен...
Всё сказанное выше — личное мнение, если не указано обратное.
Re[11]: [C#, Этюд] base.ToString
От: namespace  
Дата: 14.04.12 10:21
Оценка:
То, что сгенерирован класс с методом — понятно.
Ненормально то, что если вызвать тот метод "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
    }
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.