Covariance and Contravariance in Generics
MSDN said:
Covariance
Enables you to use a more derived type than originally specified.
You can assign an instance of IEnumerable<Derived> (IEnumerable(Of Derived) in Visual Basic) to a variable of type IEnumerable<Base>.
Contravariance
Enables you to use a more generic (less derived) type than originally specified.
You can assign an instance of IEnumerable<Base> (IEnumerable(Of Base) in Visual Basic) to a variable of type IEnumerable<Derived>.
Enables you to use a more derived type than originally specified.
You can assign an instance of IEnumerable<Derived> (IEnumerable(Of Derived) in Visual Basic) to a variable of type IEnumerable<Base>.
Contravariance
Enables you to use a more generic (less derived) type than originally specified.
You can assign an instance of IEnumerable<Base> (IEnumerable(Of Base) in Visual Basic) to a variable of type IEnumerable<Derived>.
using System; using System.Collections.Generic; namespace CoAndContra { class Animal { public virtual void Statement() { Console.WriteLine("I'm an Animal!"); } } class FruitBat : Animal { public new void Statement() { Console.WriteLine("I'm a FruitBat!"); } } class DingBat : Animal { public new void Statement() { Console.WriteLine("I'm a DingBat!"); } } class Program { static void Main(string[] args) { // Polymorphism // Polymorphism (C# Programming Guide) // https://msdn.microsoft.com/en-in/library/ms173152(v=vs.110).aspx List<Animal> animals = new List<Animal>(); animals.Add(new FruitBat()); animals.Add(new FruitBat()); foreach (Animal anim in animals) { anim.Statement(); // I'm an Animal!, twice // change "new" to "override" and it will print FruitBat instead } foreach (Animal anim in animals) { // we can cast because each anim is a FruitBat ((FruitBat)anim).Statement(); // I'm a FruitBat!, twice } //animals.Add(new DingBat()); //foreach (Animal anim in animals) { // // we cannot cast a DingBat to a FruitBat // ((FruitBat)anim).Statement(); // InvalidCastException //} // Covariance // Covariance and Contravariance in Generics // https://msdn.microsoft.com/en-in/library/dd799517(v=vs.110).aspx // IEnumerable is covariant (the out keyword): // public interface IEnumerable<out T> : IEnumerable { // [__DynamicallyInvokable] // IEnumerator<T> GetEnumerator(); // } / (code from dotPeek) IEnumerable<FruitBat> bats = new List<FruitBat>() { new FruitBat(), new FruitBat() }; // because IEnumerable is covariant we can do this: IEnumerable<Animal> anims = bats; foreach (Animal anim in anims) { anim.Statement(); // I'm an Animal!, twice } // this looks much like ordinary polymorphism // Contravariance // The parameter T in Action<T> is contravariant (in): // public delegate void Action<in T>(T obj); Action<Animal> animalAction = (obj) => { Console.WriteLine(obj.GetType().Name); }; // because of this contravariance we can do this: Action<FruitBat> fruitbatAction = animalAction; fruitbatAction(new FruitBat()); // FruitBat Console.WriteLine("Press any key to exit."); Console.ReadKey(); } } }
0 Comments On This Entry
Trackbacks for this entry [ Trackback URL ]
← March 2021 →
S | M | T | W | T | F | S |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | |
7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 30 | 31 |
Tags
My Blog Links
Recent Entries
-
-
-
Co and Contravariance, briefly
on Nov 06 2016 03:38 AM
-
-
Recent Comments
Search My Blog
3 user(s) viewing
3 Guests
0 member(s)
0 anonymous member(s)
0 member(s)
0 anonymous member(s)