using System.Collections.Generic;
interface ICovariant<out T>
void Acknowledge(Action<T> callback);
interface IContravariant<in T>
void DoSomething<T2>() where T2 : T;
interface IVariant<in Tin, out Tout>
IEnumerable<Tout> GetAll();
interface IDerivedVariant<Tin, Tout> : IVariant<Tin, Tout>
public delegate T CovariantDelegate<out T>(double num);
public delegate void ContravariantDelegate<in T>(T obj);
public delegate Tout VariantDelegate<in Tin, out Tout>(Tin obj);
public static void Main()
Console.WriteLine("\n\n************** COVARIANT IEnumerable<T> ********************");
IEnumerable<string> strings = new List<string>() { "www.techpointfunda.com", "Tech Point Fundamentals" };
IEnumerable<object> objects = strings;
foreach (var item in objects)
Console.WriteLine("\n\n************** CONTRAVARIANT IComparer<T> ********************");
Father f1 = new Father() { Id = 1, Name = "Tech Point Fundamentals" };
Father f2 = new Father() { Id = 1, Name = "Tech Point Fundamentals" };
IComparer<Father> Fcomparer = new Comparer();
if (Fcomparer.Compare(f1, f2) == 0)
Console.WriteLine("Both Objects are equal");
Console.WriteLine("Both Objects are not equal");
Console.WriteLine("\n\n************** VARIANT DELEGATES ********************");
CovariantDelegate<string> fun = new CovariantDelegate<string>(Program.Covariant<string>);
Console.WriteLine(fun(10.5));
CovariantDelegate<Int32> fun2 = (double num) => Convert.ToInt32(num);
Console.WriteLine(fun(20.5));
ContravariantDelegate<string> fun3 = new ContravariantDelegate<string>(Program.Contravariant<string>);
fun3("Tech Point Fundamentals");
ContravariantDelegate<string> fun4 = (string str) => Console.WriteLine(str);
fun4("www.techpointfunda.com");
Console.WriteLine("\n\n************** COVARIANT ARRAY ********************");
object[] arrayRefType = new String[5];
arrayRefType[0] = "www.techpointfunda.com";
arrayRefType[1] = "Tech Point Fundamentals";
foreach (var item in arrayRefType)
static T Covariant<T>(double number)
return (T)Convert.ChangeType(number, typeof(T));
static void Contravariant<T>(T input)
Console.WriteLine(input);
public class Comparer : IComparer<GrandFather>
public int Compare(GrandFather x, GrandFather y)
return string.CompareOrdinal(x.Name, y.Name);
public class GrandFather : Object
public int Id { get; set; }
public string Name { get; set; }
public class Father: GrandFather
public int Age { get; set; }
public string City { get; set; }