C# Covariance

  Рет қаралды 7,663

Coding Tutorials

Coding Tutorials

Күн бұрын

Coding Tutorial: Is a bag of apples a kind of bag of fruit? It all comes down to covariance.
Source code available at: github.com/Jas...

Пікірлер: 35
@CodingTutorialsAreGo
@CodingTutorialsAreGo 4 жыл бұрын
Any questions? Just post a comment. Download the source code at github.com/JasperKent/Covariant-Assignment And subscribe to keep up to date: kzbin.info/door/qWQzlUDdllnLmtgfSgYTCA
@mohitkumar-jv2bx
@mohitkumar-jv2bx 3 жыл бұрын
This video is so underrated. finally a great explanation of covariance that I could understand.
@Rhysling2
@Rhysling2 Жыл бұрын
Best tutorial I have seen on covariance. This deserves much more attention.
@jheysonlima
@jheysonlima 2 жыл бұрын
Man... Just found your channel and your explanations are so clear and concise, hope you get millions of subscribers... Keep up with the great job! Thank you sir!
@th3R341W3n
@th3R341W3n Жыл бұрын
Theeee best ever covariance explanation!
@stinknay
@stinknay Жыл бұрын
i lucked out, this is the first video i watched and i kind of got it the first time, when watching a second time it made even more sense. thanks.
@TheJessejunior
@TheJessejunior Жыл бұрын
incredible! never had understood these over years.
@paulofernandoee
@paulofernandoee 2 жыл бұрын
I read the msdn docs, saw other vídeos and couldn't understand, with you i finally got It, thanks! But would you mind giving an example of a real world use of covariance?
@peternguyen9382
@peternguyen9382 3 жыл бұрын
This video got me more clear about covariant in c#, now i know the real reason why Microsoft adding that feature to c#.
@CodingTutorialsAreGo
@CodingTutorialsAreGo 3 жыл бұрын
Glad you found it helpful.
@peternguyen9382
@peternguyen9382 3 жыл бұрын
@@CodingTutorialsAreGo thanks so much for helping! I really appreciate and happy when you reply.
@ZachBugay
@ZachBugay 2 жыл бұрын
Excellently explained. Great job.
@iAndrewMontanai
@iAndrewMontanai 2 жыл бұрын
That code below is also covariance? Everyone mentions only generic interfaces, delegates, array examples. Employee emp = new Manager(); Or static void Work(Employee e) { switch(e) { case Manager m: m.DoManagerWork(); break; case Developer d: ..... break; case Employee emp: ..... break; } }
@CodingTutorialsAreGo
@CodingTutorialsAreGo 2 жыл бұрын
The concept of covariance only really applies when you have collections of objects where the element in the collection is a base class. The 'co' means that the inheritance patterns of the collection and the element go in the same direction (just as with contravariance they go in opposite directions). Your first example is simply polymorphism - a base class reference refers to a derived class object. The switch example is actually a case of dynamic downcasting (safely converting a base class reference type to a derived class reference type). In more traditional code it is the equivalent of: if (e is Manager) ((Manager)e).DoManagerWork(); Doing it a switch as you've shown is much neater, using the pattern matching features introduced in C#8, but it's conceptually the same.
@peternguyen9382
@peternguyen9382 3 жыл бұрын
Hello! when you say " there is an inheritance relationship between IEnumerable and List by adding the Out keyword, so when we add the Out keyword to the interface behind the scene the compiler will "understand" List implement the interface IEnumerable ? Or because the IEnumerable is just the read-only inteface and it is safe in this case so the compiler allow us to do so? Thanks so much.
@CodingTutorialsAreGo
@CodingTutorialsAreGo 3 жыл бұрын
Hi Peter, When the interface is declared as 'IEnumerable', the 'out' keyword does two things. Firstly, it says that wherever T is used in the interface, it can only be in a context where objects of type T are coming out of the interface not going in. Essentially, that means that we can only use T as a return type, not as a parameter type, which would be passing data in (such as Add(T t)). The second thing is, it now allows statements such as 'IEnumerable collectionOfFruit = new List();' It can do that safely, because it knows (from the first point) that there is no method on IEnumerable which allows you to add or insert a Fruit. If there were and Add (Fruit), then you could add a Banana with 'collectionOfFruit.Add(new Banana());' which means you could add a Banana to a List of Apples, which is clearly wrong, and prevented by this mechanism. It's worth noting that without the 'out' (which hasn't always been in C#, and which we could miss off in our own code) we would be able to have List implement IEnumerable, but we wouldn't be able to do the assignment 'IEnumerable collectionOfFruit = new List();' Hope that helps.
@vladmaiorov1072
@vladmaiorov1072 3 ай бұрын
You have two Synchronous Yield Return in Collections playlist and no C# Contravariance
@DedicatedManagers
@DedicatedManagers 3 жыл бұрын
At 6:33why can you add a banana to the bag of apples? Didn’t you overwrite the add method with the type of apples? Or does it not overwrite because of overloading? (I am a JavaScript programmer trying to learn C#)
@CodingTutorialsAreGo
@CodingTutorialsAreGo 3 жыл бұрын
Thanks for the question. Essentially, the reason we can't add a Banana to a BagOfApples is one of definition. A BagOfApples is only allowed to contain Apples - it's not just a Bag that happens to contain only Apples at the moment. In JavaScript, although that's still a concept you might want, it's hard to enforce since JavaScript is not strongly typed. You could have 'function add(apple)', but even though the parameter is called 'apple', you could still pass in anything at all, not just various types of fruit. (You could do a runtime check that it's an apple, but there's no compile-time checking.) In C# it's easy to enforce, since if you have 'void Add(Apple apple)' then the compile enforces the rules for you. And if you use a generic like 'List', instantiated as 'List' happens automatically. Of course, even in C# you could cheat in your own BagOfApples class by giving it an overload 'void Add(Banana banana)' put the point is that you don't want to. Hope that makes sense.
@DedicatedManagers
@DedicatedManagers 3 жыл бұрын
Thanks for the reply.... unfortunately I don’t think you understood my question. If you click on the number in my comment, that’s a timestamp to a point in the video where you are able to add a banana to the bag of apples.
@CodingTutorialsAreGo
@CodingTutorialsAreGo 3 жыл бұрын
@@DedicatedManagers Ah! I see. Sorry. There I'm deliberately writing bad code to highlight the problem. The Add(Apple) does not override the Add(Fruit) from the base class because it is a different overload. In some languages (e.g. C++) having a different overload in the derived class would hide the base class method and it would be unavailable (by default) in the derived class. But that's not the case in C#, and so adding a banana calls the base class method for Fruit, while adding an apple calls the derived class method for Apple.
@DedicatedManagers
@DedicatedManagers 3 жыл бұрын
@@CodingTutorialsAreGo Got it. Thanks!
@CodingTutorialsAreGo
@CodingTutorialsAreGo 3 жыл бұрын
@@DedicatedManagers My pleasure.
@padmakrishnan3377
@padmakrishnan3377 2 жыл бұрын
Wonderful video which explains the concepts so well! Thank you! I have a couple of comments:- 1) I got very confused on how you could add a banana to the bag of apples. Took me a lot of time to figure out the base class gets called. If you can draw the reader’s attention to this, it will be very useful as this polymorphism/ inheritance sometimes trips me up. 2) Is there a need to declare the Fruit class as Abstract?
@CodingTutorialsAreGo
@CodingTutorialsAreGo 2 жыл бұрын
Thanks for your comments! 1) Yeah, it's a bit tricky because C# does so much to prevent that sort of thing, so making it happen is a bit of a hack. 2) Whether or not Fruit is abstract doesn't really affect what we're doing here, but in general OO terms it should be.
@alfonsdeda8912
@alfonsdeda8912 8 ай бұрын
So if you didn't hide the get method with the new keyword the call to the get should have called the bagoffruit and worked correctly? Why this thing is even possible?
@piotrjan2927
@piotrjan2927 2 жыл бұрын
7:00 I am a bit confused. Shouldn't it fail right away when we add a banana to BagOfApples? Add method expects an instance of Apple. And Banana class is not derived from Apple. So, even though the underlying structure - List can store any kind of fruit, it appears that the Add method's parameter type should be enough to act as the gatekeeper here.
@CodingTutorialsAreGo
@CodingTutorialsAreGo 2 жыл бұрын
In C# a 'new' method in a derived class does not hie the corresponding method in the base class. So Add(Fruit) and Add(Apple) exist side-by -side as overloads, and adding a Banana choose the Fruit overload.
@piotrjan2927
@piotrjan2927 2 жыл бұрын
@@CodingTutorialsAreGo Thanks!
@小林です-n3q
@小林です-n3q 2 жыл бұрын
thank you for your help.
@FerdieSwinkels
@FerdieSwinkels 3 жыл бұрын
Very clear tutorial, thanks for the explanation!
@CodingTutorialsAreGo
@CodingTutorialsAreGo 3 жыл бұрын
Glad it was helpful.
@sergeyt4118
@sergeyt4118 3 жыл бұрын
I still could not get it from the business reasoning standpoint: why building such perversive multi-layered abstractions? what's the point besides that one programmer could do something wrong (there are thousands ways we could f..kup here and there - but thats why tests were invented) ... and to prevent it other programmers invented other strange things ... that later could lead for yet other programmers (who struggle with these perversive abstracts) to introduce new bugs due to complexity constructs now being actively accepted into mainstream (because every other dev wants to show he is cool too, or just smarter and thus irreplaceable, or needs a payrise) ... what's wrong with just sticking to the KISS principle? - the code would be 10-15...50% longer (although more humanly readable)? - ok, let it be; to me this seems to justify avoidance of risks of complexity and dangerious bugs it brings manyfold. I am 40+ (so have some life understanding and managerial experience) and I come from the business side of the world. Though I'm still a noob in c# (but keep trying) learning it for some time - but can't throw away a strong impression that business overpays the IT world substantially not just because of hype, but also for some internal competition and smartass tactics programmers apply within the community which reflects on the code and IT products too; and imho this needs to be stopped untill its too late :)
@CodingTutorialsAreGo
@CodingTutorialsAreGo 3 жыл бұрын
In terms of the business benefit it's pretty straightforward: abstract class Person {} class Employee : Person {} class Customer : Person {} void ProcessPersons (IEnumerable people) {...} List employees = new List {...} ProcessPersons(employees); The last line only works because of covariance.
@auronedgevicks7739
@auronedgevicks7739 10 ай бұрын
why can't someone simply explain covariance without all these convoluted concepts.
C# Contravariance
13:02
Coding Tutorials
Рет қаралды 3,8 М.
Implementing IEnumerable
17:35
Coding Tutorials
Рет қаралды 11 М.
When u fight over the armrest
00:41
Adam W
Рет қаралды 26 МЛН
Человек паук уже не тот
00:32
Miracle
Рет қаралды 4,2 МЛН
Walking on LEGO Be Like... #shorts #mingweirocks
00:41
mingweirocks
Рет қаралды 7 МЛН
C# Equality and Hashcodes
27:05
Coding Tutorials
Рет қаралды 8 М.
Covariance and Contravariance
13:31
Christopher Okhravi
Рет қаралды 16 М.
C#. Covariance and Contravariance in generic interfaces.
6:35
ExtremeCode
Рет қаралды 82 М.
Covariance and Contravariance Clearly Explained in C# - A Deeper Look
14:18
IAsyncEnumerable and Yield Return
14:23
Coding Tutorials
Рет қаралды 3,7 М.
What is Covariance and Contravariance in C#: A Complete Overview
11:58
C# 11 - Generic Math(s)
17:58
Coding Tutorials
Рет қаралды 4,4 М.
Covariance Revisited
18:18
Coding Tutorials
Рет қаралды 1,2 М.
Stackalloc and Spans
30:17
Coding Tutorials
Рет қаралды 11 М.
When u fight over the armrest
00:41
Adam W
Рет қаралды 26 МЛН