Язык программирования C#9 и платформа .NET5. Страница 169
interface IRegularPointy : IPointy{ int SideLength { get; set; } int NumberOfSides { get; set; } int Perimeter => SideLength * NumberOfSides; // Статические члены также разрешены в версии C# 8 static string ExampleProperty { get; set; } static IRegularPointy() => ExampleProperty = "Foo";}Статические конструкторы не должны иметь параметры и могут получать доступ только к статическим свойствам и методам. Для обращения к статическому свойству интерфейса добавьте к операторам верхнего уровня следующий код:
Console.WriteLine($"Example property: {IRegularPointy.ExampleProperty}");IRegularPointy.ExampleProperty = "Updated";Console.WriteLine($"Example property: {IRegularPointy.ExampleProperty}");Обратите внимание, что к статическому свойству необходимо обращаться через интерфейс, а не переменную экземпляра.
Использование интерфейсов в качестве параметров
Учитывая, что интерфейсы являются допустимыми типами, можно строить методы, которые принимают интерфейсы в качестве параметров, как было проиллюстрировано на примере метода
CloneMe()IDraw3Dnamespace CustomInterfaces{ // Моделирует способность визуализации типа в трехмерном виде. public interface IDraw3D { void Draw3D(); }}Далее сконфигурируйте две из трех фигур (
CircleHexagon// Circle поддерживает IDraw3D.class ThreeDCircle : Circle, IDraw3D{ ... public void Draw3D() => Console.WriteLine("Drawing Circle in 3D!"); }}// Hexagon поддерживает IPointy и IDraw3D.class Hexagon : Shape, IPointy, IDraw3D{ ... public void Draw3D() => Console.WriteLine("Drawing Hexagon in 3D!");}На рис. 8.2 показана обновленная диаграмма классов в Visual Studio.

Теперь если вы определите метод, принимающий интерфейс
IDraw3DIDraw3DProgram// Будет рисовать любую фигуру, поддерживающую IDraw3D.static void DrawIn3D(IDraw3D itf3d){ Console.WriteLine("-> Drawing IDraw3D compatible type"); itf3d.Draw3D();}Далее вы можете проверить, поддерживает ли элемент в массиве
ShapeDrawIn3D()Console.WriteLine("***** Fun with Interfaces *****\n");Shape[] myShapes = { new Hexagon(), new Circle(), new Triangle("Joe"), new Circle("JoJo") } ;for(int i = 0; i < myShapes.Length; i++){ // Can I draw you in 3D? if (myShapes[i] is IDraw3D s) { DrawIn3D(s); }}Ниже представлен вывод, полученный из модифицированной версии приложения. Обратите внимание, что в трехмерном виде отображается только объект
HexagonShapeIDraw3D***** Fun with Interfaces *****...-> Drawing IDraw3D compatible typeDrawing Hexagon in 3D!Использование интерфейсов в качестве возвращаемых значений
Интерфейсы могут также применяться в качестве типов возвращаемых значений методов. Например, можно было бы написать метод, который получает массив объектов
ShapeIPointy// Этот метод возвращает первый объект в массиве,// который реализует интерфейс IPointy.static IPointy FindFirstPointyShape(Shape[] shapes){ foreach (Shape s in shapes) { if (s is IPointy ip)