Generic Типы и UpCast к базовому интерфейсному типу(ковариантность обобщений) - C#

Узнай цену своей работы

Формулировка задачи:

Всем привет, имеется следующий код:
public abstract class Shape { }
    public class Circle : Shape { }
 
    public interface IContainer<T>
    {
        T Figure { get; set; }
    }
 
    public class Container<T> : IContainer<T>
    {
        public T Figure { get; set; }
 
        public Container(T figure)
        {
            this.Figure = figure;
        }
    }
 
    class Program
    {
        static void Main()
        {
            Circle circle = new Circle();
 
            IContainer<Circle> container = new Container<Circle>(circle);
 
            Console.WriteLine(container.Figure.ToString());
 
            // Delay.
            Console.ReadKey();
        }
    }
Итак, вкратце - что я понял в данном примере. В данном примере мы сперва создаем абстрактный класс с именем Shape{}, затем мы создаем конкретный класс с именем Circle - который наследуется от абстрактного класса shape. далее мы создаем открытый интерфейс с именем IContainer - параметризированный - указателем места заполнения типом Т , и в теле данного интерфейса, мы создаем абстрактное авто-свойство с именем Figure - типа указателя места заполнения типа Т. Далее vss создаем класс с именем Container - который реализует интерфейс IContainer, который в свою очередь(интерфейс) параметризирован типом места заполнения типом Т. В теле класса Container мы реализуем абстрактное свойство Figure, и после этого мы создаем конструктор, который принимает один аргумент типа указателя места заполнения типом Т, и в теле этого конструктора мы авто свойству Figure присваиваем значение аргумента данного конструктора нашему свойству. Далее, в классе Program, в теле метода Main(), мы создаем экземпляр класса Circle - который как мы помним наследуется от абстрактного класса Shape. На строке:
IContainer<Circle> container = new Container<Circle>(circle);
- мы создаем переменную с именем container - типа базового интерфейсного типа IContainer, а параметр типа места заполнения типом Т у этого базового интерфейсного типа мы "закрываем" нашим типом Circle. Условно разделим приведенную ниже строку на две части: IContainer<Circle> container =

new Container<Circle>(circle);

(подчеркнутая - первая часть ,

жирная - вторая часть

) -

в итоге

мы ожидаем создаваемый во второй части строки - экземпляр класса Container - ожидаем привести его к базовому интерфейсному типу Icontainer, но в самом созданном экземпляре будет хранится свойство того типа, которым мы "закрываем" место заполнения типом Т при создании данного экземпляра - а т.к в данном случае мы "закрыли" при создании экземпляра типом Circle, то в данном случае внутри данного экземпляра будет храниться свойство Figure типа Circle(а точнее реализация этого свойства из конкретного класса Container наследуемого от интерфейса IContainer)

Вот мой вопрос:

с абстрактным классом Shape{} и конкретным классом Circle{} - наследующим его - все понятно. Затем, кто-нибудь объясните

толком

и по человечески что такое интерфейс и для чего он нужен (нет, я конечно его изучал, но толком не понял; вот например про делегаты мне простым языком объяснили так - "Делегаты — это способ сделать следующее: взять произвольный кусок кода, упаковать его в объект (экземпляр делегата) и вызвать этот кусок кода в любом месте, куда получится передать ссылку на наш экземпляр делегата." - может это и не совсем правильно, но это понятно!) С авто свойством, его реализацией и конструктором - ине тоже все понятно. также не понятно зачем автор курса говорит: "но в самом созданном экземпляре будет хранится свойство" - с какого перепугу? Т.е как я догоадываюсь(но не понимаю навернякка) - в экземпляре хранится то, что переданно в него конструктором(в нашем случае пользовательским) - а т.к аргумент конструктора через ключнвое слово this принимает значение метода set, то косвинно (через конструктор) мы как бы принимаем в экземпляр значение свойства. И

мой самый главный вопрос

также вытекает из "что такое интерфейсы - толком" - непонятно зачем мы передаем конструктору уже готовый экземпляр класса Circle, - т.е неужели мы его(этот экземпляр передаваемый как аргумент конструктора) приводим к типу этого интерфейса. напоследок вот картинка, на которой я пытался разобраться в ситуации: приложено к теме

Решение задачи: «Generic Типы и UpCast к базовому интерфейсному типу(ковариантность обобщений)»

textual
Листинг программы
public T Figure { get; set; }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

13   голосов , оценка 3.923 из 5
Похожие ответы