none
Путаница типов при ковариантности в структуре RRS feed

  • Вопрос

  • Всем привет! сейчас смотрю цыкл уроков по c#, и в одном из уроков в данном примере кода

    using System;
    
    // Ковариантность не применима к массивам элементов структурных типов.
    
    namespace ArrayCovariant
    {
        public interface IAnimal
        {
            void Voice();
        }
    
        public struct Dog : IAnimal
        {
            public void Voice()
            {
                Console.WriteLine("Gav-Gav");
            }
        }
    
        class Program
        {
            static void Main()
            {
                // 1
                Dog[] dogs = { new Dog(), new Dog(), new Dog() };
    
                //IAnimal[] animal = dogs; // Ковариантность.
                //dogs = array;  // Контрвариантность.
                ValueType i = new Int32() as ValueType;
    
                // 2
                int[] vector = new int[3] { 1, 2, 3 };
                //object[] array = vector; // Ковариантность
    
    
                // Задержка.
                Console.ReadKey();
            }
        }
    }

    меня смущает вот что:

    //IAnimal[] animal = dogs; // Ковариантность.

    смущает не сам комментарий, а то ,что автор на время его снимает и говорит следующие:

    "Сняв комментарий, мы увидим, что у нас возникает ошибка при попытке совершить UpCast всех элементов массива структурного типа(массив dogs) к базовому типу Object" - но разве он не должен был сказать "... к базовому интерфейсному типу"? Ведь мы все же пытаемся совершить ковариантность к базовому интерфейсному типу, а он ведь же не наследуется от Object как мне известно?

    Так вот, в чем мой вопрос: это ошибка автора курса или он все верно сказал? Если он сказал верноЮ то объясните пожалуйста почему!

    Пример кода не мой а учебный. Взят с сайта ITVDN.COM, с курса "C# Essebtial" -урок №8.

    Буду очень благодарен за помощь!


    • Изменено BadCatss 27 января 2016 г. 10:20 редактировал текст вопроса
    27 января 2016 г. 10:17

Ответы

  • Очень сложно сказать что имел в виду другой человек. К  тому же в такой интересной теме как коваринатность.

    Если коротко, раскоментирование вот этих строчек:

    IAnimal[] animal = dogs;
    //object[] array = vector;

    Дает ошибку компиляции. И это правильно, т.к. здесь написан бред.

    Если бы это отрабатывало, то т.к. работа здесь идет с одним объектом (массивом в памяти), то при сработавшем приведении типов через переменную animal мы бы могли присвоить элементам массива ссылки на объекты классов не являющихся производными от Dog. То-же самое и при приведении к object.

    Как я уже сказал тема ковариантности весьма специфична и на мой взгляд про нее имеет смысл говорить в Generic типах, в делегатах. Что пытался показать автор? Боюсь кроме автора вам никто не подскажет.Собирать сюда примеры лень, если хотите можете глянуть вот эту презентацию. Там правда только примеры и пара определений, но может разберетесь.

    27 января 2016 г. 12:59
    Отвечающий

Все ответы

  • Добрый день,

    думаю вам стоит обсуждать данный код с автором данного курса.

    27 января 2016 г. 10:21
  • к сожалению у меня нет такой возможности!:-( Мне бы очень хотелось узнать Ваше мнение если это возможно, или хотя бы какое-то наставление(напутствие или источники с информацией!)

    Буду Вам ОЧЕНЬ благодарен!

    27 января 2016 г. 11:26
  • Очень сложно сказать что имел в виду другой человек. К  тому же в такой интересной теме как коваринатность.

    Если коротко, раскоментирование вот этих строчек:

    IAnimal[] animal = dogs;
    //object[] array = vector;

    Дает ошибку компиляции. И это правильно, т.к. здесь написан бред.

    Если бы это отрабатывало, то т.к. работа здесь идет с одним объектом (массивом в памяти), то при сработавшем приведении типов через переменную animal мы бы могли присвоить элементам массива ссылки на объекты классов не являющихся производными от Dog. То-же самое и при приведении к object.

    Как я уже сказал тема ковариантности весьма специфична и на мой взгляд про нее имеет смысл говорить в Generic типах, в делегатах. Что пытался показать автор? Боюсь кроме автора вам никто не подскажет.Собирать сюда примеры лень, если хотите можете глянуть вот эту презентацию. Там правда только примеры и пара определений, но может разберетесь.

    27 января 2016 г. 12:59
    Отвечающий
  • спасибо Вам ОГРАМНОЕ ха ответ и презентацию!
    27 января 2016 г. 13:15
  • Пожалуйста. Если вы только знакомитесь с языком C#, то не упирайтесь на этой теме. Посмотрите, испугайтесь и идите дальше. ООП нельзя выучить наскоком. Что поняли - то супер. Программируйте, спрашивайте, читайте другие книги про ООП, в какой-то момент происходит прорыв и у вас в голове сложится целостная картина, до тех пор будет хорошо, если вы будите применять некоторые подходы в меру своего понимания.
    27 января 2016 г. 13:35
    Отвечающий
  • Не могли бы Вы помочь мне с данным вопросом? 

    https://social.msdn.microsoft.com/Forums/ru-RU/a36a2a3c-64f2-42ed-90f3-3fabc2f74a70/-?forum=programminglanguageru

    (просто гиперссылкой оно не хочет вставляться)

    27 января 2016 г. 14:15
  • Я как понял при попытке присвоить структуру в интерфейсный тип, сначала структура пакуется в объект в куче, который вернет ссылку на него. Интерфейсы являются ссылочными типами. Может я не понял вопроса.

    Mak Arti



    28 января 2016 г. 7:37