B
B
BadCats2016-06-18 23:10:03
C++ / C#
BadCats, 2016-06-18 23:10:03

Generic Types and UpCast to base interface type(Generic covariance)?

Hello everyone, I have the following code:

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();
        }
    }

So, in short - what I understood in this example.
In this example, we first create an abstract class named Shape{}, then we create a concrete class named Circle - which inherits from the abstract shape class.
next, we create a public interface named IContainer - parameterized - with a placeholder of type T , and in the body of this interface, we create an abstract auto-property named Figure - of type placeholder type T.
Next, we create a vss class named Container - which implements the IContainer interface, which in turn (the interface) is parameterized by the placeholder type T.
In the body of the Container class, we implement the abstract property Figure, and after that we create a constructor that takes one argument of the type of placeholder type T, and in the body of this constructor, we automatically assign the value of the argument of this constructor to our property in the body of this constructor.
Next, in the Program class, in the body of the Main() method, we create an instance of the Circle class - which, as we remember, is inherited from the abstract Shape class.
On the line:
IContainer<Circle> container = new Container<Circle>(circle);

- we create a variable named container - of the type of the base interface type IContainer, and we "close" the type parameter of the place of filling with the type T of this base interface type with our Circle type.
Let's conditionally divide the line below into two parts:
IContainer container = new Container(circle);
( Italics - the first part , bold - the second part )
- as a resultwe expect to be created in the second part of the line - an instance of the Container class - we expect to cast it to the base interface type Icontainer, but the created instance itself will store a property of the type with which we "close" the filling place with type T when creating this instance - and since in this case, we "closed" when creating an instance of the Circle type, then in this case, the Figure property of the Circle type will be stored inside this instance (or rather, the implementation of this property from a specific Container class inherited from the IContainer interface)
Here is my question: with the abstract class Shape{ } and the concrete class Circle{} - inheriting it - everything is clear.
Then someone please explainand as a human being what an interface is and what it is for (no, of course I studied it, but I didn’t really understand it; for example, they explained it to me in simple terms about delegates like this - “Delegates are a way to do the following: take an arbitrary piece of code, pack it into object (delegate instance) and call this piece of code anywhere where we can pass a reference to our delegate instance." - this may not be entirely correct, but it's understandable!)
With an auto property, its implementation and constructor - everything is also clear .
it is also not clear why the author of the course says: "but the property will be stored in the created instance itself" - with what fright? That is, as I guess (but I don’t understand for sure) - the instance stores what is passed to it by the constructor (in our case, custom) - and since the constructor argument takes the value of the set method through the this keyword, then indirectly (through the constructor ) we kind of take the value of the property into the instance.
And my most important question also stems from "what are interfaces - plainly" - it is not clear why we pass a ready-made instance of the Circle class to the constructor - that is, do we really cast it (this instance passed as a constructor argument) to the type of this interface.
Finally, here is a picture in which I tried to understand the situation:
7d54967f17164d939117237127bc7925.jpg

Answer the question

In order to leave comments, you need to log in

2 answer(s)
W
WarFollowsMe, 2016-06-20
@BadCats

In C#, using interfaces, they implement an important property of OOP - polymorphism. In short, this is the selection of the same properties and methods of objects, without being tied to their type. In simple words, for example, we have a number of objects: a chair, a table, a cup, a sad pug and the Churyumov-Gerasimenko comet. And for example, the task is to track their movement. All objects are of different types and it is impossible to bring them to one common one. This is where interfaces come to the rescue. Describing the properties we need

public interface INotifyCoordinateChanged
{
    string Name{get;set;}
    double X{get;set;}
    double Y{get;set;}
    double Z{get;set;}
    event Action<INotifyCoordinateChanged> CoordinateChanged;
}

and if we implement this interface for all objects, then now it is enough for us to track changes in the list
PS And your example is very strange. Interesting for explaining what topic it was used. It's just an absolutely meaningless hodgepodge, pmsm.

#
#algooptimize #bottize, 2016-06-18
@user004

Read about oop with code examples.
In practice, the need and benefit are obvious.
For dynamic languages ​​and slack-typed languages, the conditions are less strict, but the benefits are the same.
Too lazy to chew, maybe the other will not.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question