Рейтинговые книги
Читем онлайн Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 164 165 166 167 168 169 170 171 172 ... 642

}

Console.ReadLine();

Обратите внимание, что когда применяется ключевое слово as, отпадает необходимость в наличии логики try/catch, т.к. если ссылка не является null, то известно, что вызов происходит для действительной ссылки на интерфейс.

Получение ссылок на интерфейсы: ключевое слово is (обновление в версии 7.0)

Проверить, реализован ли нужный интерфейс, можно также с помощью ключевого слова is (о котором впервые упоминалось в главе 6). Если интересующий объект не совместим с указанным интерфейсом, тогда возвращается значение false. В случае предоставления в операторе имени переменной ей назначается надлежащий тип, что устраняет необходимость в проверке типа и выполнении приведения. Ниже показан обновленный предыдущий пример:

Console.WriteLine("***** Fun with Interfaces *****n");

...

if(hex2 is IPointy itfPt3)

{

  Console.WriteLine("Points: {0}", itfPt3.Points);

}

else

{

  Console.WriteLine("OOPS! Not pointy...");

}

 Console.ReadLine();

Стандартные реализации (нововведение в версии 8.0)

Как упоминалось ранее, в версии C# 8.0 методы и свойства интерфейса могут иметь стандартные реализации. Добавьте к проекту новый интерфейс по имени IRegularPointy, предназначенный для представления многоугольника заданной формы. Вот код интерфейса:

namespace CustomInterfaces

{

  interface IRegularPointy : IPointy

  {

    int SideLength { get; set; }

    int NumberOfSides { get; set; }

    int Perimeter => SideLength * NumberOfSides;

  }

}

Добавьте к проекту новый файл класса по имени Square.cs, унаследуйте класс от базового класса Shape и реализуйте интерфейс IRegularPointy:

namespace CustomInterfaces

{

  class Square: Shape,IRegularPointy

  {

    public Square() { }

    public Square(string name) : base(name) { }

    // Метод Draw() поступает из базового класса Shape

    public override void Draw()

    {

      Console.WriteLine("Drawing a square");

    }

(window.adrunTag = window.adrunTag || []).push({v: 1, el: 'adrun-4-390', c: 4, b: 390})

    // Это свойство поступает из интерфейса IPointy

    public byte Points => 4;

    // Это свойство поступает из интерфейса IRegularPointy.

    public int SideLength { get; set; }

    public int NumberOfSides { get; set; }

    // Обратите внимание, что свойство Perimeter не реализовано.

  }

}

Здесь мы невольно попали в первую "ловушку", связанную с использованием стандартных реализаций интерфейсов. Свойство Perimeter, определенное в интерфейсе IRegularPointy, в классе Square не определено, что делает его недоступным экземпляру класса Square. Чтобы удостовериться в этом, создайте новый экземпляр класса Square и выведите на консоль соответствующие значения:

Console.WriteLine("n***** Fun with Interfaces *****n");

...

var sq = new Square("Boxy")

  {NumberOfSides = 4, SideLength = 4};

sq.Draw();

// Следующий код не скомпилируется:

// Console.WriteLine($"{sq.PetName} has {sq.NumberOfSides} of length

{sq.SideLength} and a perimeter of {sq.Perimeter}");

Взамен экземпляр Square потребуется явно привести к интерфейсу IRegularPointy (т.к. реализация находится именно там) и тогда можно будет получать доступ к свойству Perimeter. Модифицируйте код следующим образом:

Console.WriteLine($"{sq.PetName} has {sq.NumberOfSides} of length {sq.SideLength} and a

perimeter of {((IRegularPointy)sq).Perimeter}");

Один из способов обхода этой проблемы — всегда указывать интерфейс типа. Измените определение экземпляра Square, указав вместо типа Square тип IRegularPointy:

IRegularPointy sq = new Square("Boxy") {NumberOfSides = 4, SideLength = 4};

Проблема с таким подходом (в данном случае) связана с тем, что метод Draw() и свойство PetName в интерфейсе не определены, а потому на этапе компиляции возникнут ошибки.

Хотя пример тривиален, он демонстрирует одну из проблем, касающихся стандартных реализаций. Прежде чем задействовать это средство в своем коде, обязательно оцените последствия того, что вызывающему коду должно быть известно, где находятся реализации.

Статические конструкторы и члены (нововведение в версии 8.0)

Еще одним дополнением интерфейсов в C# 8.0 является возможность наличия в них статических конструкторов и членов, которые функционируют аналогично статическим членам в определениях классов, но определены в интерфейсах. Добавьте к интерфейсу IRegularPointy статическое свойство и статический конструктор:

1 ... 164 165 166 167 168 169 170 171 172 ... 642
На этой странице вы можете бесплатно читать книгу Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю бесплатно.
Похожие на Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю книги

Оставить комментарий