Re[9]: поведение new в interface
От: Сокрашт  
Дата: 28.02.07 03:47
Оценка:
Здравствуйте, Poul_Ko, Вы писали:

P_K>И вот ещё пример кода для размышления:

P_K>
P_K>    public interface B
P_K>    {
P_K>        string Name
P_K>        { get; }
P_K>    }
P_K>    public interface A
P_K>    {
P_K>        string Name
P_K>        { set; }
P_K>    }

P_K>    internal interface AB : A, B
P_K>    {}

P_K>    internal class MyClass : AB
P_K>    {
P_K>        public string _name;

P_K>        string A.Name
P_K>        {
P_K>            set { _name = value; }
P_K>        }
P_K>        string B.Name
P_K>        {
P_K>            get { return _name; }
P_K>        }
P_K>    }
P_K>

P_K>Этот код прекрасно компилируется, хотя, казалось бы, MyClass не содержит реализации AB.

Пример интересный, но не сказать, чтобы здесь понадобилось много размышлений. Интерфейс AB является производным от двух базовых интерфейсов, А и В, но собственных методов не имеет. Поэтому при построении класса, реализующего AB, достаточно реализовать методы A и B.
Re[9]: поведение new в interface
От: Сокрашт  
Дата: 28.02.07 04:25
Оценка:
Здравствуйте, Poul_Ko, Вы писали:

P_K>Вот именно. Чтобы убедиться в этом, попробуйте в классе MyClass сделать explicit-реализацию интерфейса AB.

...

P_K>Этот код прекрасно компилируется, хотя, казалось бы, MyClass не содержит реализации AB.


(Вдогонку) Что здесь самое интересное, так это скрытая опасность. Если попробовать добавить в реализацию модификатор доступа:

public interface B
...
public interface A
...

internal interface AB : A, B
{}

internal class MyClass : AB
{
     public string _name;

     string A.Name
     {
          public set { _name = value; }
     }
      string B.Name
     {
          public get { return _name; }
     }
}

то будут проблемы!
Re[10]: поведение new в interface
От: Сокрашт  
Дата: 28.02.07 04:37
Оценка:
Виноват, у меня ошибка в предыдущем сообшении. Конечно, я хотел сказать:

public interface B
...
public interface A
...

internal interface AB : A, B
{}

internal class MyClass : AB
{
     public string _name;

     public string A.Name  //так нельзя
     {
           set { _name = value; }
     }
     public string B.Name  //так нельзя
     {
           get { return _name; }
     }
}
Re[11]: поведение new в interface
От: Poul_Ko Казахстан  
Дата: 28.02.07 06:00
Оценка:
Здравствуйте, Сокрашт, Вы писали:

...
С>
С>public interface B
С>...
С>public interface A
С>...
С>internal class MyClass : AB
С>{
С>...
С>     public string A.Name  //так нельзя
С>...
С>     public string B.Name  //так нельзя
С>...
С>

Естественно, так нельзя! При explicit-реализации интерфейса нельзя указывать модификатор доступа.
Brainbench transcript #6370594
Re[8]: поведение new в interface
От: Feral  
Дата: 28.02.07 06:10
Оценка:
Здравствуйте, nikov, Вы писали:

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


F>>Вернемся к примеру здесь
Автор: Feral
Дата: 26.02.07
, у Интерфейса AB есть и геттер и сеттер, как и у базовых интерфейсов, но обращаться через AB к ним нельзя, хотя реализация и get и set присутствует.


N>Там у AB нет ни геттера, ни сеттера. Наследование у интерфейсов работает не так, как у классов. Интерфейс не наследует члены базовых интерфейсов.



Т.е. получается что для интерфейсов никакой vtbl нет? как же тогда происходит связывание с нужной реализацией?

То что MyClass наследуя AB, на самом деле наследует сначала AB потом B это понятно, но если я добавил в AB метод то в vtbl должно быть 2 записи для двух разных функций: для AB.get_Name B.get_Name, но получается что ссылаются они на одну и туже реализацию.

Если в MyClass явно указать что реализация AB.Name, то компилятор ругнется, что не найдена реализация для B.Name, но если этого не указывать, то оба(!) геттера будут сслаться на один и тот же метод!
Re[12]: поведение new в interface
От: Сокрашт  
Дата: 28.02.07 06:57
Оценка:
Здравствуйте, Poul_Ko, Вы писали:

P_K>Естественно, так нельзя! При explicit-реализации интерфейса нельзя указывать модификатор доступа.


А почему нельзя? (Вообще-то мне известно, почему нельзя, но хотелось бы знать Ваш вариант ответа).
Re[9]: поведение new в interface
От: Feral  
Дата: 28.02.07 08:44
Оценка:
F>То что MyClass наследуя AB, на самом деле наследует сначала AB потом B это понятно, но если я добавил в AB метод то в vtbl должно быть 2 записи для двух разных функций: для AB.get_Name B.get_Name, но получается что ссылаются они на одну и туже реализацию.

F>Если в MyClass явно указать что реализация AB.Name, то компилятор ругнется, что не найдена реализация для B.Name, но если этого не указывать, то оба(!) геттера будут сслаться на один и тот же метод!


up.
Методы в интерфейсах являются виртуальными?
Re[13]: поведение new в interface
От: Poul_Ko Казахстан  
Дата: 28.02.07 08:45
Оценка:
Здравствуйте, Сокрашт, Вы писали:

С>А почему нельзя? (Вообще-то мне известно, почему нельзя, но хотелось бы знать Ваш вариант ответа).


Мне кажется, что разработчики языка сочли такую возможность лишней, так как область видимости таких мемберов всегда однозначно определяется областью видимости интерфейса. Это всего лишь моё предположение, интересно было бы проверить его с помощью Reflector'а...
Brainbench transcript #6370594
Re[14]: поведение new в interface
От: Poul_Ko Казахстан  
Дата: 28.02.07 08:54
Оценка: +1
Глянул в спецификацию, там по этому поводу сказано:

Explicit interface member implementations have different accessibility characteristics than other members. Because explicit interface member implementations are never accessible through their fully qualified name in a method invocation or a property access, they are in a sense private. However, since they can be accessed through an interface instance, they are in a sense also public.

Brainbench transcript #6370594
Re[9]: up
От: Feral  
Дата: 28.02.07 16:40
Оценка:
Здравствуйте, Feral, Вы писали:

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


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


F>>>Вернемся к примеру здесь
Автор: Feral
Дата: 26.02.07
, у Интерфейса AB есть и геттер и сеттер, как и у базовых интерфейсов, но обращаться через AB к ним нельзя, хотя реализация и get и set присутствует.


N>>Там у AB нет ни геттера, ни сеттера. Наследование у интерфейсов работает не так, как у классов. Интерфейс не наследует члены базовых интерфейсов.



F>Т.е. получается что для интерфейсов никакой vtbl нет? как же тогда происходит связывание с нужной реализацией?


F>То что MyClass наследуя AB, на самом деле наследует сначала AB потом B это понятно, но если я добавил в AB метод то в vtbl должно быть 2 записи для двух разных функций: для AB.get_Name B.get_Name, но получается что ссылаются они на одну и туже реализацию.


F>Если в MyClass явно указать что реализация AB.Name, то компилятор ругнется, что не найдена реализация для B.Name, но если этого не указывать, то оба(!) геттера будут сслаться на один и тот же метод!
Re[9]: поведение new в interface
От: nikov США http://www.linkedin.com/in/nikov
Дата: 28.02.07 18:20
Оценка: 2 (1)
Здравствуйте, Feral, Вы писали:

F>Т.е. получается что для интерфейсов никакой vtbl нет? как же тогда происходит связывание с нужной реализацией?


То, какой метод данного класса на какой (или какие) методы интерфейсов отображаются, решается на этапе компиляции. Этот процесс описан в Ecma-334, 20.4.2 Interface mapping. Когда вызов метода проиходит через переменную, имеющую интерфейсный тип, то на этапе компиляции, естественно, невозможно определить, в каком классе (или упакованной структуре) находится вызываемый метод. Но, если эта переменная не равна null, то в рантайме можно однозначно определить тип объекта, на который она ссылается, и, соответственно, реализацию метода, который должен быть вызван.

F>То что MyClass наследуя AB, на самом деле наследует сначала AB потом B это понятно, но если я добавил в AB метод то в vtbl должно быть 2 записи для двух разных функций: для AB.get_Name B.get_Name, но получается что ссылаются они на одну и туже реализацию.


Да, на одну.

F>Если в MyClass явно указать что реализация AB.Name, то компилятор ругнется, что не найдена реализация для B.Name, но если этого не указывать, то оба(!) геттера будут сслаться на один и тот же метод!


Да, так и дожно быть. Это описано здесь: Ecma-334, 20.4.2 Interface mapping.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.