static void Main(string[] args) { //delegates covariance Animal a = new Bird(); ReturnAnimalDelegate d = GetBird; //Delegates contravariance TakeBirdDelegate d2 = Eat; d2(new Bird()); //arrays covariance Animal[] animals = new Bird[10]; //This is broken: //animals[0] = new Human(); //generics covariance IProcess <Animal> animalProcessor = new AnimalProcessor <Animal>(); IProcess <Bird> birdProcessor = new AnimalProcessor <Bird>(); Animal animal = birdProcessor.Process(); animalProcessor = birdProcessor; IEnumerable <Animal> animalList = new List <Bird>(); //generic contravariance IZoo <Animal> animalZoo = new Zoo <Animal>(); animalZoo.Add(new Animal()); IZoo <Bird> birdZoo = new Zoo <Bird>(); birdZoo = animalZoo; birdZoo.Add(new Bird()); }
static void Main(string[] args) { #region === DELEGATES === Console.WriteLine("=== DELEGATES ==="); // Covariance with delegates ReturnAnimalDelegate d = GetBird; Animal a = d(); Console.WriteLine($"a: {a.GetType().Name}"); // shows Bird type not Animal // Contravariance with delegates TakeBirdDelegate d2 = Eat; d2(new Bird()); // performs Eat not Fly // Contravariance with delegates EXAMPLE Action <Bird> contravariant2 = new Action <Animal>((Animal animal) => { }); #endregion #region === ARRAYS === Console.WriteLine("=== ARRAYS ==="); // Covariance with arrays Animal[] animals = new Bird[10]; //animals[0] = new Human(); throw exception by run Console.WriteLine($"animals: {animals.GetType().Name}"); // shows Bird[] type not Animal[] #endregion #region === GENERICS === Console.WriteLine("=== GENERICS ==="); // Covariance with generics IProcess <Animal> animalProcessor = new AnimalProcessor <Animal>(); IProcess <Bird> birdProcessor = new AnimalProcessor <Bird>(); animalProcessor = birdProcessor; var processType = animalProcessor.Process(); Console.WriteLine($"processType: {processType.GetType().Name}"); // shows Bird type not Animal // Covariance with generics EXAMPLE IEnumerable <Animal> animals2 = new List <Bird>(); // Contravariance with generics IZoo <Animal> animalZoo = new Zoo <Animal>(); animalZoo.Add(new Animal()); IZoo <Bird> birdZoo = new Zoo <Bird>(); Console.WriteLine($"birdZoo.Count: {birdZoo.Count}"); // shows 0 birdZoo = animalZoo; birdZoo.Add(new Bird()); Console.WriteLine($"birdZoo.Count: {birdZoo.Count}"); // shows 2 not 1, because birdZoo points to animalZoo // Contravariance with generics EXAMPLE IComparer <Bird> comparer = new CustomComparer <Animal>(); #endregion Console.ReadKey(); }
public static void Main(string[] args) { /************************* * 1- D E L E G A T E S * return type is covariant and the parameters are contravariant *************************/ Animal a = new Bird(); //a- return type example ReturnAnimalDelegate da = GetAnimal; ReturnAnimalDelegate db = GetBird; a = db(); //The other way (reverse asignement) around doesn't work ReturnBirdDelegate dbb = GetAnimal; //Failed otherwise dbb().Fly() should work, //failed the same way as Bird b = new Animal(); //b- the parameters example TakeBirdDelegate tb = Fly; TakeAnimalDelegate ta = Eat; tb = Eat; //In delegate reverse asignement is contravariant in argument type (success in passing the Bird instead of animal) ta(new Bird()); //(reverse asignement) failed tb(new Animal()); ta = Fly; /**************************************S U M M A R Y ********************************************* * for delegates the return type is covariant and the parameters are contravariant, * the delegates are the only construct in C# that supports Covariance & Contravariance *********************************************************************************************/ /************************* * 2- A R R A Y S * Array with refrence type are also covariants *************************/ //assignment is preserved Animal[] animals = new Bird[10]; animals[0] = new Humain(); //compilers doesn't complain but runtime Exception (ArrayTypeMismatchException) /************************* * 3- G E N E R I C S * *************************/ IProcess <Animal> animalProcessor = new AnimalProcessor <Animal> (); IProcess <Bird> birdProcessor = new AnimalProcessor <Bird> (); //covariance makes sense, since birdProcessor.Process() return bird which is an animal Animal animal = birdProcessor.Process(); //Cannot implicitly convert type 'IProcess<Bird>' to 'IProcess<Animal>'. An explicit conversion exists (are you missing a cast? //even the compiler gives an error, since .net 4.0 we could make it covariant by adding an out keyword to the interface animalProcessor = birdProcessor; //public interface IEnumerable<out T> : IEnumerable IEnumerable <Animal> animalList = new List <Bird> (); //generic contravariance IZoo <Animal> animalZoo = new Zoo <Animal>(); animalZoo.add(new Animal()); //we could also a animalZoo.add(new Bird()); IZoo <Bird> birdZoo = new Zoo <Bird>(); birdZoo.add(new Bird()); //generic contravariance birdZoo = animalZoo; birdZoo = new Zoo <Animal>(); //doesn't works birdZoo = new Zoo <Humain>(); /***************************************************************************** * public interface IComparer<in T> : * makes senses if we want to compare not only birds by any abstract * animal with birds ******************************************************************************/ //Also the same goes for generics delegates func and action }
static void Main(string[] args) { { Tuple <int, int, int, int, int, int, int, Tuple <int> > t = new Tuple <int, int, int, int, int, int, int, Tuple <int> >(1, 2, 3, 4, 5, 6, 7, new Tuple <int>(8)); } { Anomymous anomymous = new Anomymous(); anomymous.CallAnomymous(11); anomymous.CallAnomymous(22); anomymous.CallAnomymous(33); } { List <Employee> employees = new List <Employee>() { new Employee("first1", "last1"), new Employee("first2", "last2"), new Employee("first3", "last3"), new Employee("first4", "last4") }; Predicate <Employee> fun = (Employee e) => e.FullName.Contains("first3"); Employee emp1 = employees.Find(e => e.FullName.Contains("first3")); Employee emp2 = employees.Find(fun); Employee emp3 = employees.Find(FindEmployee); } { DateTime d1 = new DateTime(2070, 1, 1); DateTime d2 = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day); DateTime d4 = DateTime.SpecifyKind(DateTime.Today, DateTimeKind.Unspecified); DateTime d3 = DateTime.ParseExact("20181002", "yyyyMMdd", System.Globalization.CultureInfo.InvariantCulture); } { IEnumerable <Person> persons = new List <Person>() { new Person() { FirstName = "f1", LastName = "l1", Age = 15 }, new Person() { FirstName = "f2", LastName = "l2", Age = 15 }, new Person() { FirstName = "f3", LastName = "l3", Age = 15 }, new Person() { FirstName = "f4", LastName = "l4", Age = 15 } }; var query = from person in persons.AsQueryable() select persons; } { NameValueCollection nvc = new NameValueCollection(); } { dynamic obj = new ExpandoObject(); FlagEnum color = (FlagEnum)(FlagEnum.Red - FlagEnum.Blue); Type type = typeof(FlagEnum); FlagEnum red = FlagEnum.Red; bool isBlue = color.HasFlag(FlagEnum.Blue); string desc = (red.GetType().GetField(red.ToString()).GetCustomAttributes(typeof(System.ComponentModel.DescriptionAttribute), false)[0] as System.ComponentModel.DescriptionAttribute).Description; } { var a = new Animal <string>(); Person p = new Person { FirstName = "", Age = 5 }; p.Print <int>(5); p.MyEvent1 += (sender, n) => Console.WriteLine("MyEvent1 fired"); p.MyEvent1 += delegate { Console.WriteLine("MyEvent1 fired"); }; p.MyEvent2 += (sender, n) => Console.WriteLine("MyEvent2 fired"); p.TriggerEvent(); } { List <Person> people = new List <Person>() { new Person() { Age = 10 }, new Person() { Age = 20 }, new Person() { Age = 30 }, new Person() { Age = 40 } }; var readonlyP = people.AsReadOnly(); readonlyP[0].Age = 100; IZoo <Animal> aniZoo = new Zoo <Animal>(); aniZoo.Add(new Animal()); IZoo <Bird> birdZoo = new Zoo <Bird>(); birdZoo.Add(new Bird()); birdZoo = aniZoo; IProcessor <Animal> animalProcessor = new AnimalProcessor <Animal>(); IProcessor <Animal> animalProcessor2 = new AnimalProcessor <Bird>(); } { ReturnAnimalDelegate a = GetAnimal; ReturnAnimalDelegate a2 = GetBird; ReturnBirdDelegate b = GetBird; //ReturnBirdDelegate b2 = GetAnimal; TakeAnimalDelegate ta = Eat; //TakeAnimalDelegate ta2 = Fly; TakeBirdDelegate tb = Fly; TakeBirdDelegate tb2 = Eat; } { object o = "abc"; string s = (string)o; object o2 = (object)s; Type t = o.GetType(); Type t1 = s.GetType(); bool e = t == t1; List <int> ints = new List <int>(); Comparison <Person> c = (p1, p2) => p1.Age - p2.Age; bool re = ReferenceEquals(null, null); } { MyFunc myf1 = Fun1; myf1 += delegate(int a2, int b2) { return(a2.ToString()); }; myf1 += (a3, b3) => b3.ToString(); string r1 = myf1(10, 20); } { Type ty = Type.GetType("ConsoleTest.Employee, ConsoleTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a950b44ee98bfbc8"); object obj = Activator.CreateInstance(ty, new object[] { "wen1", "chen1" }); Employee emp = new Employee("wen", "chen"); Type type = emp.GetType(); } { Employee emp = new Employee("wen", "chen"); string fn1 = emp.FullName; string fn = ((IPerson)emp).GetFullName(); } { Dictionary <string, string> dic1 = new Dictionary <string, string>(); dic1.Add("key1", "value1"); dic1.Add("key1", "value1"); dic1.Add("key1", "value1"); } { Person p1 = new Person(); p1.FirstName = "Wen"; p1.LastName = "Chen"; p1.Age = 33; Person p2 = p1.ShallowCopy(); p2.Age = 100; p2.FirstName = "w2"; p2.LastName = "c2"; } { Predicate <int> pre1 = e => e > 10; Predicate <int> pre2 = (e) => e > 10; Predicate <int> pre3 = (e) => { e++; return(e > 10); }; Predicate <int> pre4 = delegate(int e) { e++; return(e > 10); }; bool rePre1 = pre1(5); Func <string> fun1 = delegate() { return(""); }; string reFun1 = fun1(); Func <int, string, string> fun2 = (p1, p2) => p1.ToString() + p2; string reFun2 = fun2(100, "abc"); Func <string> fun3 = () => "abcd"; string reFun3 = fun3(); List <int> ints = new List <int>(); MyFunc myFunc1 = delegate(int a, int b) { return(a.ToString() + b.ToString()); }; MyFunc myFunc2 = (a, b) => a.ToString() + b.ToString(); string reMyFunc1 = myFunc2(11, 21); Action action1 = () => {; }; var obj1 = new { P1 = 500, P2 = "some", P3 = new Object() }; string res = MyGeneric <int, string>((e) => e.ToString()); IEnumerable <Person> persons = new List <Person>() { new Person() { FirstName = "a1", LastName = "b1", Age = 10 }, new Person() { FirstName = "a2", LastName = "b2", Age = 20 }, new Person() { FirstName = "a3", LastName = "b3", Age = 30 } }; foreach (Person p in persons) { p.FirstName = "xy"; } } }