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

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

Читать книгу Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен, Эндрю Троелсен . Жанр: Программирование.
Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен
Название: Язык программирования C#9 и платформа .NET5
Дата добавления: 26 август 2023
Количество просмотров: 561
(18+) Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних просмотр данного контента СТРОГО ЗАПРЕЩЕН! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту для удаления материала.
Читать онлайн

Язык программирования C#9 и платформа .NET5 читать книгу онлайн

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

В 10-м издании книги описаны новейшие возможности языка C# 9 и .NET 5 вместе с подробным "закулисным" обсуждением, призванным расширить навыки критического мышления разработчиков, когда речь идет об их ремесле.
Книга охватывает ASP.NET Core, Entity Framework Core и многое другое наряду с последними обновлениями унифицированной платформы .NET, начиная с улучшений показателей производительности настольных приложений Windows в .NET 5 и обновления инструментария XAML и заканчивая расширенным рассмотрением файлов данных и способов обработки данных.
Все примеры кода были переписаны с учетом возможностей последнего выпуска C# 9.

1 ... 92 93 94 95 96 ... 407 ВПЕРЕД
Перейти на страницу:
class="code">    Console.WriteLine("Drawing a 3D Circle");

  }

}

После перекомпиляции вы обнаружите следующее предупреждение:

'ThreeDCircle.Draw()' hides inherited member 'Circle.Draw()'. To make

the current member override that implementation, add the override keyword.

Otherwise add the new keyword.

'Shapes.ThreeDCircle.Draw() скрывает унаследованный член Shapes.Circle.Draw().

Чтобы текущий член переопределял эту реализацию, добавьте ключевое слово override.

В противном случае добавьте ключевое слово new.'

Дело в том, что у вас есть производный класс (ThreeDCircle), который содержит метод, идентичный унаследованному методу. Решить проблему можно несколькими способами. Вы могли бы просто модифицировать версию метода Draw() в дочернем классе, добавив ключевое слово override (как предлагает компилятор). При таком подходе у типа ThreeDCircle появляется возможность расширять стандартное поведение родительского типа, как и требовалось. Однако если у вас нет доступа к файлу кода с определением базового класса (частый случай, когда приходится работать с множеством библиотек от сторонних поставщиков), тогда нет и возможности изменить метод Draw(), превратив его в виртуальный член.

В качестве альтернативы вы можете добавить ключевое слово new к определению проблемного члена Draw() своего производного типа (ThreeDCircle). Поступая так, вы явно утверждаете, что реализация производного типа намеренно спроектирована для фактического игнорирования версии члена из родительского типа (в реальности это может оказаться полезным, если внешнее программное обеспечение каким-то образом конфликтует с вашим программным обеспечением).

// Этот класс расширяет Circle и скрывает унаследованный метод Draw().

class ThreeDCircle : Circle

{

  // Скрыть любую реализацию Draw(), находящуюся выше в иерархии.

  public new void Draw()

  {

    Console.WriteLine("Drawing a 3D Circle");

  }

}

Вы можете также применить ключевое слово new к любому члену типа, который унаследован от базового класса (полю, константе, статическому члену или свойству). Продолжая пример, предположим, что в классе ThreeDCircle необходимо скрыть унаследованное свойство PetName:

class ThreeDCircle : Circle

{

  // Скрыть свойство PetName, определенное выше в иерархии.

   public new string PetName { get; set; }

  // Скрыть любую реализацию Draw(), находящуюся выше в иерархии.

  public new void Draw()

  {

    Console.WriteLine("Drawing a 3D Circle");

  }

}

Наконец, имейте в виду, что вы по-прежнему можете обратиться к реализации скрытого члена из базового класса, используя явное приведение, как описано в следующем разделе. Вот пример:

...

// Здесь вызывается метод Draw(), определенный в классе ThreeDCircle.

ThreeDCircle o = new ThreeDCircle();

o.Draw();

// Здесь вызывается метод Draw(), определенный в родительском классе!

((Circle)o).Draw();

Console.ReadLine();

Правила приведения для базовых и производных классов

Теперь, когда вы умеете строить семейства взаимосвязанных типов классов, нужно изучить правила, которым подчиняются операции приведения классов. Давайте возвратимся к иерархии классов для сотрудников, созданной ранее в главе, и добавим несколько новых методов в класс Program (если вы прорабатываете примеры, тогда откройте проект Employees в Visual Studio). Как описано в последнем разделе настоящей главы, изначальным базовым классом в системе является System.Object. По указанной причине любой класс "является" Object и может трактоваться как таковой. Таким образом, внутри переменной типа object допускается хранить экземпляр любого типа:

static void CastingExamples()

{

  // Manager "является" System.Object, поэтому в переменной

  // типа object можно сохранять ссылку на Manager.

  object frank = new Manager("Frank Zappa", 9, 3000, 40000, "111-11-1111", 5);

}

В проекте Employees классы Manager, SalesPerson и PtSalesPerson расширяют класс Employee, а потому допустимая ссылка на базовый класс может хранить любой из объектов указанных классов. Следовательно, приведенный далее код также законен:

static void CastingExamples()

{

  // Manager "является" System.Object, поэтому в переменной

  // типа object можно сохранять ссылку на Manager.

  object frank = new Manager("Frank Zappa", 9, 3000, 40000, "111-11-1111", 5);

  // Manager тоже "является" Employee.

  Employee moonUnit = new Manager("MoonUnit Zappa", 2, 3001, 20000,

                                  "101-11-1321", 1);

  // PtSalesPerson "является" SalesPerson.

  SalesPerson jill = new PtSalesPerson("Jill", 834, 3002, 100000,

                                       "111-12-1119", 90);

}

Первое правило приведения между типами классов гласит, что когда два класса связаны отношением "является", то всегда можно безопасно сохранить объект производного типа в ссылке базового класса. Формально это называется неявным приведением, поскольку оно "просто работает" в соответствии с законами наследования. В результате появляется возможность строить некоторые мощные программные конструкции. Например, предположим, что в текущем классе Program определен новый метод:

static void GivePromotion(Employee emp)

{

  // Повысить зарплату...

  // Предоставить место на парковке компании...

  Console.WriteLine("{0} was promoted!", emp.Name);

}

Из-за того, что данный метод принимает единственный параметр типа Employee, в сущности, ему можно передавать объект любого унаследованного от Employee класса, учитывая наличие отношения "является":

static void CastingExamples()

{

  // Manager "является" System.Object, поэтому в переменной

  // типа object можно сохранять ссылку на Manager.

  object frank = new Manager("Frank Zappa", 9, 3000, 40000, "111-11-1111", 5);

  // Manager также "является" Employee.

  Employee moonUnit = new Manager("MoonUnit Zappa", 2, 3001, 20000,

                                  "101-11-1321", 1);

  GivePromotion(moonUnit);

  // PtSalesPerson "является" SalesPerson.

  SalesPerson jill = new PtSalesPerson("Jill", 834, 3002, 100000,

                                       "111-12-1119", 90);

  GivePromotion(jill);

}

Предыдущий код компилируется благодаря неявному приведению от типа базового класса (Employee) к производному классу. Но что, если вы хотите также вызвать метод GivePromotion() с объектом frank (хранящимся в общей ссылке System.Object)? Если вы передадите объект frank методу GivePromotion() напрямую, то получите ошибку на этапе компиляции:

object frank = new Manager("Frank Zappa", 9, 3000, 40000, "111-11-1111", 5);

// Ошибка!

GivePromotion(frank);

Проблема в том, что вы пытаетесь передать переменную, которая объявлена как принадлежащая не к типу Employee, а к более общему типу System.Object. Учитывая, что

1 ... 92 93 94 95 96 ... 407 ВПЕРЕД
Перейти на страницу:
Комментарии (0)