Проблема с таким подходом (в данном случае) связана с тем, что метод
Draw
и свойство
PetName
в интерфейсе не определены, а потому на этапе компиляции возникнут ошибки.
Хотя пример тривиален, он демонстрирует одну из проблем, касающихся стандартных реализаций. Прежде чем задействовать это средство в своем коде, обязательно оцените последствия того, что вызывающему коду должно быть известно, где находятся реализации.
Статические конструкторы и члены (нововведение в версии 8.0)
Еще одним дополнением интерфейсов в C# 8.0 является возможность наличия в них статических конструкторов и членов, которые функционируют аналогично статическим членам в определениях классов, но определены в интерфейсах. Добавьте к интерфейсу
IRegularPointy
статическое свойство и статический конструктор:
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";
}
Статические конструкторы не должны иметь параметры и могут получать доступ только к статическим свойствам и методам. Для обращения к статическому свойству интерфейса добавьте к операторам верхнего уровня следующий код:
Обратите внимание, что к статическому свойству необходимо обращаться через интерфейс, а не переменную экземпляра.
Использование интерфейсов в качестве параметров
Учитывая, что интерфейсы являются допустимыми типами, можно строить методы, которые принимают интерфейсы в качестве параметров, как было проиллюстрировано на примере метода
CloneMe
ранее в главе. Предположим, что вы определили в текущем примере еще один интерфейс по имени
IDraw3D
:
namespace CustomInterfaces
{
// Моделирует способность визуализации типа в трехмерном виде.
public interface IDraw3D
{
void Draw3D;
}
}
Далее сконфигурируйте две из трех фигур (
Circle
и
Hexagon
) с целью поддержки нового поведения:
// 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.
Теперь если вы определите метод, принимающий интерфейс
IDraw3D
в качестве параметра, тогда ему можно будет передавать по существу любой объект, реализующий
IDraw3D
. Попытка передачи типа, не поддерживающего необходимый интерфейс, приводит ошибке на этапе компиляции. Взгляните на следующий метод, определенный в классе