C# Covariance

2020 ж. 11 Мау.
6 904 Рет қаралды

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/JasperKent/Covaria...

Пікірлер
  • Any questions? Just post a comment. Download the source code at github.com/JasperKent/Covariant-Assignment And subscribe to keep up to date: kzhead.info/tools/qWQzlUDdllnLmtgfSgYTCA.html

    @CodingTutorialsAreGo@CodingTutorialsAreGo3 жыл бұрын
  • This video is so underrated. finally a great explanation of covariance that I could understand.

    @mohitkumar-jv2bx@mohitkumar-jv2bx2 жыл бұрын
  • Best tutorial I have seen on covariance. This deserves much more attention.

    @Rhysling2@Rhysling28 ай бұрын
  • 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!

    @jheysonlima@jheysonlima2 жыл бұрын
  • Theeee best ever covariance explanation!

    @th3R341W3n@th3R341W3n Жыл бұрын
  • 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.

    @stinknay@stinknay6 ай бұрын
  • incredible! never had understood these over years.

    @TheJessejunior@TheJessejunior8 ай бұрын
  • Excellently explained. Great job.

    @ZacharyBugay@ZacharyBugay Жыл бұрын
  • thank you for your help.

    @user-jx1dm4qz1p@user-jx1dm4qz1p2 жыл бұрын
  • 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?

    @paulofernandoee@paulofernandoee2 жыл бұрын
  • 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?

    @padmakrishnan3377@padmakrishnan33772 жыл бұрын
    • 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.

      @CodingTutorialsAreGo@CodingTutorialsAreGo2 жыл бұрын
    • 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?

      @alfonsdeda8912@alfonsdeda89122 ай бұрын
  • This video got me more clear about covariant in c#, now i know the real reason why Microsoft adding that feature to c#.

    @peternguyen9382@peternguyen93823 жыл бұрын
    • Glad you found it helpful.

      @CodingTutorialsAreGo@CodingTutorialsAreGo3 жыл бұрын
    • @@CodingTutorialsAreGo thanks so much for helping! I really appreciate and happy when you reply.

      @peternguyen9382@peternguyen93823 жыл бұрын
  • 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.

    @peternguyen9382@peternguyen93823 жыл бұрын
    • 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.

      @CodingTutorialsAreGo@CodingTutorialsAreGo3 жыл бұрын
  • 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.

    @piotrjan2927@piotrjan2927 Жыл бұрын
    • 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.

      @CodingTutorialsAreGo@CodingTutorialsAreGo Жыл бұрын
    • @@CodingTutorialsAreGo Thanks!

      @piotrjan2927@piotrjan2927 Жыл бұрын
  • 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#)

    @DedicatedManagers@DedicatedManagers3 жыл бұрын
    • 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.

      @CodingTutorialsAreGo@CodingTutorialsAreGo3 жыл бұрын
    • 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.

      @DedicatedManagers@DedicatedManagers3 жыл бұрын
    • @@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.

      @CodingTutorialsAreGo@CodingTutorialsAreGo3 жыл бұрын
    • @@CodingTutorialsAreGo Got it. Thanks!

      @DedicatedManagers@DedicatedManagers3 жыл бұрын
    • @@DedicatedManagers My pleasure.

      @CodingTutorialsAreGo@CodingTutorialsAreGo3 жыл бұрын
  • 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; } }

    @iAndrewMontanai@iAndrewMontanai2 жыл бұрын
    • 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.

      @CodingTutorialsAreGo@CodingTutorialsAreGo2 жыл бұрын
  • Very clear tutorial, thanks for the explanation!

    @FerdieSwinkels@FerdieSwinkels3 жыл бұрын
    • Glad it was helpful.

      @CodingTutorialsAreGo@CodingTutorialsAreGo3 жыл бұрын
  • 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 :)

    @sergeyt4118@sergeyt41183 жыл бұрын
    • 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.

      @CodingTutorialsAreGo@CodingTutorialsAreGo3 жыл бұрын
  • why can't someone simply explain covariance without all these convoluted concepts.

    @auronedgevicks7739@auronedgevicks77394 ай бұрын
KZhead