Telegram Group & Telegram Channel
День двадцать восьмой. #ЗаметкиНаПолях
Явная реализация интерфейсного метода (EIMI)
class SomeType : IDisposable
{
public void Dispose()
{
Console.WriteLine(“public Dispose”);
}
void IDisposable.Dispose()
{
Console.WriteLine(“IDisposable.Dispose”);
}
}
Если в C# перед именем метода вы ставите имя интерфейса, в котором определён этот метод, то вы создаёте явную реализацию интерфейсного метода. Этому методу нельзя указывать область доступа (private или public), однако компилятор, создавая метаданные для метода, делает его private. Поэтому единственный способ вызвать интерфейсный метод – обратиться через переменную этого интерфейсного типа.

Явная реализация методов интерфейса служит двум главным целям:
1) Поскольку она недоступна через экземпляры класса, это позволяет исключить эти методы из общедоступного интерфейса класса. Это, в частности, полезно, когда класс реализует внутренний интерфейс, который не представляет интереса для пользователей класса.
Например, List<T> реализует IList<T> неявно, а IList (необобщённый интерфейс) явно. Это значит, что, когда вы используете класс напрямую, вы увидите только обобщённые методы и не увидите методы, принимающие Object.
Допустим, вы создали экземпляр List<Person>. Если бы IList был реализован неявно, тогда у вас было бы два метода Add, напрямую доступных из класса: Add(Person item) и Add(Object item), что разрушило бы безопасность типов, предлагаемую обобщениями. Вызов list.Add("Foo") успешно бы скомпилировался, поскольку была бы автоматически выбрана перегруженная версия Add(Object).

2) Явные реализации методов интерфейса позволяют избежать путаницы между двумя реализациями методов с одинаковой сигнатурой. Без этого классам было бы невозможно иметь разные реализации интерфейсных членов с одинаковой сигнатурой и типом возвращаемого значения, а также классам было бы невозможно иметь вообще какие-либо реализации членов интерфейса с одинаковой сигнатурой, но разными типами возвращаемого значения.

В следующем примере класс ресторана реализует два интерфейса для выдачи вариантов меню: на вынос IWindow и «в ресторане» IRestaurant. Эти интерфейсы имеют одинаковые методы GetMenu, но с разными типами возвращаемого значения. Также ресторан может иметь свою собственную реализацию метода GetMenu, не имеющую отношения к интерфейсным методам. Основная программа запрашивает все три метода, приводя экземпляр класса к интерфейсному типу для вызова явных реализаций интерфейсных методов.
using System;

public abstract class Menu { }
public class WindowMenu : Menu { }
public class RestaurantMenu : Menu { }

public interface IWindow { WindowMenu GetMenu(); }
public interface IRestaurant { RestaurantMenu GetMenu(); }

public sealed class Pizzeria : IWindow, IRestaurant
{
//Явная реализация интерфейсного метода для IWindow
WindowMenu IWindow.GetMenu() => new WindowMenu();

//Явная реализация интерфейсного метода для IRestaurant
RestaurantMenu IRestaurant.GetMenu() => new RestaurantMenu();

//Дополнительный открытый метод, не имеющий отношения к интерфейсам
public string GetMenu() => "Public method";
}

class Program
{
static void Main(string[] args)
{
Pizzeria mp = new Pizzeria();
//открытый метод
Console.WriteLine(mp.GetMenu());

//Метод IWindow.GetMenu
var windowMenu = ((IWindow) mp).GetMenu();
Console.WriteLine(windowMenu.ToString());

//Метод IRestaurant.GetMenu
var restaurantMenu = ((IRestaurant) mp).GetMenu();
Console.WriteLine(restaurantMenu.ToString());

Console.ReadLine();
}
}

Источник: Джеффри Рихтер “CLR via C#”. 3-е изд. – СПб.: Питер, 2012. Глава 13.
👍2



tg-me.com/NetDeveloperDiary/36
Create:
Last Update:

День двадцать восьмой. #ЗаметкиНаПолях
Явная реализация интерфейсного метода (EIMI)

class SomeType : IDisposable
{
public void Dispose()
{
Console.WriteLine(“public Dispose”);
}
void IDisposable.Dispose()
{
Console.WriteLine(“IDisposable.Dispose”);
}
}
Если в C# перед именем метода вы ставите имя интерфейса, в котором определён этот метод, то вы создаёте явную реализацию интерфейсного метода. Этому методу нельзя указывать область доступа (private или public), однако компилятор, создавая метаданные для метода, делает его private. Поэтому единственный способ вызвать интерфейсный метод – обратиться через переменную этого интерфейсного типа.

Явная реализация методов интерфейса служит двум главным целям:
1) Поскольку она недоступна через экземпляры класса, это позволяет исключить эти методы из общедоступного интерфейса класса. Это, в частности, полезно, когда класс реализует внутренний интерфейс, который не представляет интереса для пользователей класса.
Например, List<T> реализует IList<T> неявно, а IList (необобщённый интерфейс) явно. Это значит, что, когда вы используете класс напрямую, вы увидите только обобщённые методы и не увидите методы, принимающие Object.
Допустим, вы создали экземпляр List<Person>. Если бы IList был реализован неявно, тогда у вас было бы два метода Add, напрямую доступных из класса: Add(Person item) и Add(Object item), что разрушило бы безопасность типов, предлагаемую обобщениями. Вызов list.Add("Foo") успешно бы скомпилировался, поскольку была бы автоматически выбрана перегруженная версия Add(Object).

2) Явные реализации методов интерфейса позволяют избежать путаницы между двумя реализациями методов с одинаковой сигнатурой. Без этого классам было бы невозможно иметь разные реализации интерфейсных членов с одинаковой сигнатурой и типом возвращаемого значения, а также классам было бы невозможно иметь вообще какие-либо реализации членов интерфейса с одинаковой сигнатурой, но разными типами возвращаемого значения.

В следующем примере класс ресторана реализует два интерфейса для выдачи вариантов меню: на вынос IWindow и «в ресторане» IRestaurant. Эти интерфейсы имеют одинаковые методы GetMenu, но с разными типами возвращаемого значения. Также ресторан может иметь свою собственную реализацию метода GetMenu, не имеющую отношения к интерфейсным методам. Основная программа запрашивает все три метода, приводя экземпляр класса к интерфейсному типу для вызова явных реализаций интерфейсных методов.
using System;

public abstract class Menu { }
public class WindowMenu : Menu { }
public class RestaurantMenu : Menu { }

public interface IWindow { WindowMenu GetMenu(); }
public interface IRestaurant { RestaurantMenu GetMenu(); }

public sealed class Pizzeria : IWindow, IRestaurant
{
//Явная реализация интерфейсного метода для IWindow
WindowMenu IWindow.GetMenu() => new WindowMenu();

//Явная реализация интерфейсного метода для IRestaurant
RestaurantMenu IRestaurant.GetMenu() => new RestaurantMenu();

//Дополнительный открытый метод, не имеющий отношения к интерфейсам
public string GetMenu() => "Public method";
}

class Program
{
static void Main(string[] args)
{
Pizzeria mp = new Pizzeria();
//открытый метод
Console.WriteLine(mp.GetMenu());

//Метод IWindow.GetMenu
var windowMenu = ((IWindow) mp).GetMenu();
Console.WriteLine(windowMenu.ToString());

//Метод IRestaurant.GetMenu
var restaurantMenu = ((IRestaurant) mp).GetMenu();
Console.WriteLine(restaurantMenu.ToString());

Console.ReadLine();
}
}

Источник: Джеффри Рихтер “CLR via C#”. 3-е изд. – СПб.: Питер, 2012. Глава 13.

BY .NET Разработчик


Warning: Undefined variable $i in /var/www/tg-me/post.php on line 283

Share with your friend now:
tg-me.com/NetDeveloperDiary/36

View MORE
Open in Telegram


telegram Telegram | DID YOU KNOW?

Date: |

Telegram Gives Up On Crypto Blockchain Project

Durov said on his Telegram channel today that the two and a half year blockchain and crypto project has been put to sleep. Ironically, after leaving Russia because the government wanted his encryption keys to his social media firm, Durov’s cryptocurrency idea lost steam because of a U.S. court. “The technology we created allowed for an open, free, decentralized exchange of value and ideas. TON had the potential to revolutionize how people store and transfer funds and information,” he wrote on his channel. “Unfortunately, a U.S. court stopped TON from happening.”

Among the actives, Ascendas REIT sank 0.64 percent, while CapitaLand Integrated Commercial Trust plummeted 1.42 percent, City Developments plunged 1.12 percent, Dairy Farm International tumbled 0.86 percent, DBS Group skidded 0.68 percent, Genting Singapore retreated 0.67 percent, Hongkong Land climbed 1.30 percent, Mapletree Commercial Trust lost 0.47 percent, Mapletree Logistics Trust tanked 0.95 percent, Oversea-Chinese Banking Corporation dropped 0.61 percent, SATS rose 0.24 percent, SembCorp Industries shed 0.54 percent, Singapore Airlines surrendered 0.79 percent, Singapore Exchange slid 0.30 percent, Singapore Press Holdings declined 1.03 percent, Singapore Technologies Engineering dipped 0.26 percent, SingTel advanced 0.81 percent, United Overseas Bank fell 0.39 percent, Wilmar International eased 0.24 percent, Yangzijiang Shipbuilding jumped 1.42 percent and Keppel Corp, Thai Beverage, CapitaLand and Comfort DelGro were unchanged.

telegram from us


Telegram .NET Разработчик
FROM USA