static void Main() { /* Пример 1 Ковариативность * Здесь делегат возвращает объект Person. Однако благодаря ковариантности * данный делегат может указывать на метод, который возвращает объект * производного типа, например, Client. */ PersonFactory personDel; personDel = BuildClient; // Ковариативность Person p = personDel("Tom"); Console.WriteLine(p.Name); /* Пример 2 Контрвариативность * Несмотря на то, что делегат в качестве параметра принимает объект Client, * ему можно присвоить метод, принимающий в качестве параметра объект базового * типа Person.*/ ClientInfo clientInfo = GetPersonInfo; // Контрвариативность Client client = new Client { Name = "Alice" }; clientInfo(client); /* Пример 3 * Благодаря использованию out мы можем присвоить делегату типа Builder<Person> * делегат типа Builder<Client> или ссылку на метод, который возвращает значение * Client.*/ Builder <Client2> clientBuilder = GetClient; Builder <Person2> personBuilder1 = clientBuilder; // Ковариативность Builder <Person2> personBuilder2 = GetClient; // Ковариативность Person2 person2 = personBuilder1("Tom"); // Вызов делегата person2.Display(); // Client: Tom /* Пример 4 * Использование ключевого слова in позволяет присвоить делегат с более * универсальным типом (GetInfo<Person>) делегату с производным типом * (GetInfo<Client>).*/ GetInfo <Person2> personInfo2 = PersonInfo; GetInfo <Client2> clientInfo2 = personInfo2; // Контрвариативность Client2 client2 = new Client2 { Name = "Jack" }; clientInfo2(client2); // Client: Jack }
private static void ClientInfo(Client2 cl) { cl.Display(); }