IEnumerable.GetEnumerator выбрасывает InvalidCastException -> Почему я не получаю ошибку времени компиляции? - PullRequest
0 голосов
/ 14 февраля 2020

Я нашел очень запутанную проблему, и я надеюсь, что вы можете помочь мне понять эту проблему. Моя цель состояла в том, чтобы иметь структуру, которую я могу легко перебрать для удобства чтения. К сожалению, я получил и InvalidCastException, и я не понимаю, почему это произошло. Я считаю, что компилятор не должен был скомпилировать его:

Первоначально

Я ожидал, что он будет работать "из коробки", потому что я позволил интерфейсу быть реализованным через поле этой структуры с помощью Reshaper, но я получил InvalidCastException при запуске моих юнит-тестов (к счастью, там и не в производстве), пытающихся перебрать мое поле.

Как я уже сказал, проблема возникла при итерации, что означает Метод GetEnumerator () генерирует исключение InvalidCastException. Что я использовал в качестве лежащего в основе объекта, который я хочу перебрать? Это ConcurrentDictionary (см. Пример кода). Я нашел несколько Вопросов, касающихся интерфейса IEnumerable.

И, насколько я могу судить, относительно реализации этого интерфейса ничего не было сделано неправильно, что, по крайней мере, заметно очевидно.

public struct test : IEnumerable<(int, string)>
{
        public ConcurrentDictionary<string,(int,string)> dictionary ;

        public IEnumerator<(int, string)> GetEnumerator()
        {
            return ((IEnumerable<(int,string)>)dictionary).GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return ((IEnumerable<(int,string)>)dictionary).GetEnumerator();
        }
}

Насколько я понимаю, ConcurrentDictionary реализует IEnumerable, и поэтому я должен иметь возможность просто переслать эти методы звонки. Сначала я подумал, что он может что-то сделать с параметром инвариантного / ковариантного типа

Но это не объясняет, что Поведение для меня. Поэтому я проверил документы microsofts: ConcurrentDictionary и обнаружил мой идиотизм: Я хотел перебирать свои значения, а не пару ключей и значений.


После долгих размышлений

Я не могу понять, почему у меня возникает ошибка во время выполнения, если во время компиляции типы работают нормально. Он должен НЕ компилироваться в первую очередь. Что мне не хватает?

У меня есть идея почему , если я посмотрю на этот ответ , но говорил о приведении IEnumerable с 1 аргументом типа * generic c против 2 generi c введите аргументы. Разве этой разницы недостаточно? Разве это не должно быть обнаружено из компилятора?

...