Re: RuntimeBinderException & dynamic
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 06.06.10 20:26
Оценка: 5 (1)
Здравствуйте, samius, Вы писали:

S>Всем привет!


S>Наткнулся на странное поведение, взял кусок кода и упростил его до минимума.

S>
S>interface IFoo
S>{
S>    void Foo(int[] v);
S>}

S>interface IFoo2
S>    : IFoo // (1)
S>{
S>    //void Foo(int[] v); // (2)
S>}

S>class FooImpl : IFoo2
S>{
S>    public void Foo(int[] v)
S>    {
S>    }
S>}

S>class Program
S>{
S>    static void Bar(IFoo2 foo, dynamic v)
S>    {
S>        foo.Foo(v); // (3)
S>        // new FooImpl().Foo(v); // (4)
S>    }

S>    static void Main()
S>    {
S>        Bar(new FooImpl(), new[] {1, 2, 3});
S>    }
S>}
S>


S>Этот код кидает исключение RuntimeBinderException с сообщением

S>

S>'ConsoleApp.IFoo' does not contain a definition for 'Foo'

Говорит что ConsoleApp.IFoo2 не содержит метода Foo.

S>Однако, если закомментировать линию, помеченную (1) и раскомментировать линию (2), то все работает. Работать так же будет и тот случай, когда в исходном варианте закомментировать линию (3) и раскомментировать (4).


S>Есть у кого-нибудь идеи, почему так происходит?


Потому что IFoo2 действительно не содержит такого метода.
Пункт 8.9.11 в Ecma-335

... consider an interface, IFoo, that has a single method. An interface, IBar, which
derives from it, is requiring that any object type that supports IBar also support IFoo. It does not say anything
about which methods IBar itself will have.


Это C# делает вид, что методы в интерфейсах "наследуются", на уровне IL не так дела обстоят.
RuntimeBinder довольно глуп, он на вход получает информацию что надо найти метод Foo для типа IFoo2, и его не находит, можете сами рефлексией посмотреть что у него такого метода нет. А пройтись по его интерфейсам, как это делает компилятор, почему-то не догадывается.

Надо багу засабмитить.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.