Re: Индексатор с параметром enum -- баг в CLR?
От: nikov США http://www.linkedin.com/in/nikov
Дата: 08.10.07 10:31
Оценка: 81 (2)
Здравствуйте, diamondio, Вы писали:

D>При попытке использовать индексаторы _всегда_ вызывается this[MyEnum en]:


Объяснение, почему в C# было принято решение поступать именно так, можно почитать в этой заметке.
Re[9]: Индексатор с параметром enum -- баг в CLR?
От: nikov США http://www.linkedin.com/in/nikov
Дата: 08.10.07 11:48
Оценка: 6 (1)
Здравствуйте, _FRED_, Вы писали:

D>>Видимо, компилятор игнорирует type cast как redundant. Хотя это смущает. Я бы ожидал, что вызовется как раз int-овый метод.


_FR>Да, это у меня ошибочка вышла


Это известное отклонение компилятора от стандарта. Хотя там написано:

An implicit enumeration conversion permits the decimal-integer-literal 0 to be converted to any enum-type.


, фактически компилятор позволяет неявное преобразование от любого constant expression, значение которого равно 0, 0.0, 0.0F или 0.0M. Похоже, это чинить пока не собираются.
Re: Индексатор с параметром enum -- баг в CLR?
От: nikov США http://www.linkedin.com/in/nikov
Дата: 08.10.07 09:35
Оценка: 1 (1)
Здравствуйте, diamondio, Вы писали:

D>Собственно вопрос -- почему такое происходит?


Это не баг. Литерал 0 может быть неявно преобразован в любой enum. А если в производном типе есть function member (в частности, индексатор) с подходящей сигнатурой, то члены базовых классов исключаются из рассмотрения. Это обсуждалось на форуме несколько раз, например здесь
Автор: nikov
Дата: 23.03.07
.

И кстати, CLR здесь не при чем — это особенность компилятора C#.
Индексатор с параметром enum -- баг в CLR?
От: diamondio  
Дата: 08.10.07 09:26
Оценка:
Добрый день!

Столкнулись со следующей ситуацией:

Есть базовый класс, содержащий индексатор с параметром int:
    public class MyBase
    {
        public string this[int en] { get { return "Int"; } }
    }


и наследник, содержащий индексатор с параметром enum:
    public class MyClass : MyBase
    {
        public string this[MyEnum en] { get { return "Enum"; } }
    }


При попытке использовать индексаторы _всегда_ вызывается this[MyEnum en]:
            MyClass c = new MyClass();
            Console.WriteLine("Enum: " + c[MyEnum.A]);
            Console.WriteLine("Int: " + c[0]);


Enum: Enum
Int: Enum


Собственно вопрос -- почему такое происходит?

Если добавить в MyClass определение нового индексатора код начинает вести себя нормально:
public string new this[int i] { { get { return base[i];} } }


Поведение устойчиво воспроизводится на .NET 1.1 и 2.0.
Re: Индексатор с параметром enum -- баг в CLR?
От: _FRED_ Черногория
Дата: 08.10.07 09:34
Оценка:
Здравствуйте, diamondio, Вы писали:

D>Собственно вопрос -- почему такое происходит?


Потому что сущёствует неявное преобразование из 0 в enum. Поэтому индексатор в наследнике оказывается предподчтительней.
Вот так будет работать, как ожидаается:
int i = 0;
Console.WriteLine(c[i]);
Console.WriteLine(c[1]);
Help will always be given at Hogwarts to those who ask for it.
Re[2]: Индексатор с параметром enum -- баг в CLR?
От: _FRED_ Черногория
Дата: 08.10.07 09:36
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Вот так будет работать, как ожидаается:


Или даже так
Console.WriteLine(c[(int)0]);
Help will always be given at Hogwarts to those who ask for it.
Re[3]: Индексатор с параметром enum -- баг в CLR?
От: diamondio  
Дата: 08.10.07 09:54
Оценка:
Здравствуйте, _FRED_, Вы писали:


_FR>
Console.WriteLine(c[(int)0]);


Так не работает. В остальном -- вы правы.

Показалось сначала, что такое поведение не только с 0, это и ввело в замешательство.
Re[4]: Индексатор с параметром enum -- баг в CLR?
От: _FRED_ Черногория
Дата: 08.10.07 10:03
Оценка:
Здравствуйте, diamondio, Вы писали:

_FR>>
Console.WriteLine(c[(int)0]);


D>Так не работает. В остальном -- вы правы.


Что именно "не работает"? У меня вызывается индексатор базового класса (с параметром int).

D>Показалось сначала, что такое поведение не только с 0, это и ввело в замешательство.


На самом деле в примере просто "режет глаза" использование именно нуля: так и кажется, что в нуле-от и лопата
Help will always be given at Hogwarts to those who ask for it.
Re[5]: Индексатор с параметром enum -- баг в CLR?
От: diamondio  
Дата: 08.10.07 10:12
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>>>
Console.WriteLine(c[(int)0]);


_FR>Что именно "не работает"? У меня вызывается индексатор базового класса (с параметром int).


А у меня -- вызывается enum-нутый.

        Console.WriteLine("Enum: " + c[MyEnum.A]);
           Console.WriteLine("Int: " + c[(int)0]);


Правда, каст к инту в IDE выделен серым -- решарпер постарался -- но вряд ли он его удаляет из кода при компиляции, верно?
Re[6]: Индексатор с параметром enum -- баг в CLR?
От: _FRED_ Черногория
Дата: 08.10.07 10:15
Оценка:
Здравствуйте, diamondio, Вы писали:

D>А у меня -- вызывается enum-нутый.

D>Console.WriteLine("Int: " + c[(int)0]);

D>Правда, каст к инту в IDE выделен серым -- решарпер постарался -- но вряд ли он его удаляет из кода при компиляции, верно?

А можешь объяснить, почему вызывается "enum-нутый"?
Help will always be given at Hogwarts to those who ask for it.
Re[7]: Индексатор с параметром enum -- баг в CLR?
От: diamondio  
Дата: 08.10.07 10:41
Оценка:
Здравствуйте, _FRED_, Вы писали:

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


D>>А у меня -- вызывается enum-нутый.

_FR>
D>>Console.WriteLine("Int: " + c[(int)0]);
_FR>

D>>Правда, каст к инту в IDE выделен серым -- решарпер постарался -- но вряд ли он его удаляет из кода при компиляции, верно?

_FR>А можешь объяснить, почему вызывается "enum-нутый"?


Видимо, компилятор игнорирует type cast как redundant. Хотя это смущает. Я бы ожидал, что вызовется как раз int-овый метод.
Re[8]: Индексатор с параметром enum -- баг в CLR?
От: _FRED_ Черногория
Дата: 08.10.07 11:36
Оценка:
Здравствуйте, diamondio, Вы писали:

D>Видимо, компилятор игнорирует type cast как redundant. Хотя это смущает. Я бы ожидал, что вызовется как раз int-овый метод.


Да, это у меня ошибочка вышла
Help will always be given at Hogwarts to those who ask for it.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.