Для получения триального ключа
заполните форму ниже
Team license
Enterprise license
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Запросите информацию о ценах
Новая лицензия
Продление лицензии
--Выберите валюту--
USD
EUR
RUB
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Бесплатная лицензия PVS-Studio для специалистов Microsoft MVP
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Для получения лицензии для вашего открытого
проекта заполните, пожалуйста, эту форму
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Мне интересно попробовать плагин на:
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Ваше сообщение отправлено.

Мы ответим вам на


Если вы так и не получили ответ, пожалуйста, проверьте папку
Spam/Junk и нажмите на письме кнопку "Не спам".
Так Вы не пропустите ответы от нашей команды.

>
>
>
Планируете взяться за .NET MAUI? Будьте…

Планируете взяться за .NET MAUI? Будьте готовы к приключениям с NullReferenceException

06 Окт 2022

.NET Multi-platform App UI – фреймворк, который пишут профессионалы. Тем не менее, код некоторых его функций выглядит так, будто разработчики забыли о последствиях разыменования нулевых ссылок.

0996_NRE_MAUI_ru/image1.png

Небольшая вводная

Не берусь судить об общем качестве проекта MAUI, но у меня есть сильные подозрения, что проекту предстоит пройти долгий путь фиксов по фидбеку от пользователей про неожиданные NullReferenceException.

Код создаёт впечатление, что авторы очень торопятся при его написании. Из-за этого во многих местах без проверок разыменовываются ссылки, которые, по мнению самих же разработчиков, могут быть нулевыми. Чтобы было понятнее, давайте взглянем на отдельные фрагменты из исходников MAUI 6.0.424.

Почему так?

Именно этот вопрос я задавал себе, когда глядел на фрагменты, представленные далее. Либо я чего-то не понял, либо разработчики MAUI пишут очень странный код.

К примеру, взгляните на фрагмент из функции AttachEvents класса AdaptiveTrigger:

void AttachEvents()
{
  ....

  _visualElement = VisualState?.VisualStateGroup?.VisualElement;
  if (_visualElement is not null)
    _visualElement.PropertyChanged += OnVisualElementPropertyChanged;

  _window = _visualElement.Window;  // <=
  ....
}

Тут выходит какая-то ерунда. Судя по двум "?." и проверке "is not null", в поле _visualElement может быть null. И буквально тут же мы видим обращение к свойству Window, но уже без проверки. Видимо, проглядели.

Ладно, идём дальше. Взгляните на фрагмент из класса FormattedString:

void OnCollectionChanged(....)
{
  ....
    foreach (object item in e.OldItems)
    {
      var bo = item as Span;
      bo.Parent = null;                   // <=
      if (bo != null)
      {
        ....
      }
  .... 
}

Опять соседние строчки. Сначала разыменовали bo, а затем вдруг решили проверить его на null. Я не знаю, падает ли этот код в каких-то случаях, но выглядит это всё странно.

А вот кусочек из класса ListView:

protected override void SetupContent(Cell content, int index)
{
  ....

  if (content != null)
    _logicalChildren.Add(content);

  content.Parent = this;
  VisualDiagnostics.OnChildAdded(this, content);
}

Тут снова какая-то ерунда. Почему в коллекцию элемент добавляется с проверкой, а к свойству мы обращаемся уже без неё?

Ещё одну "полезную" проверку на null я нашёл в конструкторе класса ShellChromeGallery:

AppShell AppShell => Application.Current.MainPage as AppShell;

public ShellChromeGallery()
{
  ....

  if (AppShell != null)
  {
    flyoutBehavior.SelectedIndex = ....;
    flyoutHeaderBehavior.SelectedIndex = ....;
  }
  else
  {
    flyoutBehavior.SelectedIndex = 1;
    flyoutHeaderBehavior.SelectedIndex = 0;
  }

  AppShell.FlyoutBackdrop = SolidColorBrush.Pink;  // <=
}

Ну тут опять всё круто: проверяем на null, выставляем при необходимости какие-то дефолтные значения, а потом сразу же падаем.

Учитывая то, как часто попадаются странные фрагменты, я даже начал думать, что проверка на равенство null – совсем не то, чем кажется. Ну, к примеру, в том же Unity оператор "==" перегружен и проверка на равенство null там работает по-особому. Однако в MAUI ничего такого я не увидел.

А почему же всё-таки так?

MAUI пишут профессионалы, но проект очень уж большой и сложный. Люди ошибаются, и это нормально. Странно другое: такие проблемы вполне могут отлавливать различные автоматизированные инструменты. К примеру, как несложно догадаться, я нашёл показанные фрагменты с помощью C# анализатора PVS-Studio. На мой взгляд, подобные инструменты сильно бы упростили жизнь разработчикам MAUI. А в целом желаю им успехов с развитием проекта.

Последние статьи:

Опрос:

Популярные статьи по теме
Что нового в .NET 7?

Дата: 16 Ноя 2022

Автор: Артём Ровенский

Вышел .NET 7, а это значит, что можно вдоволь насладиться различными нововведениями и фишками. Расскажем про самые интересные улучшения: C# 11, контейнеры, производительность, GC и прочее.
Что такое катастрофический возврат и как регулярное выражение может стать причиной ReDoS-уязвимости?

Дата: 03 Ноя 2022

Автор: Андрей Москалёв

Регулярные выражения – очень полезный и удобный инструмент для поиска и замены текста. Однако в некоторых случаях они могут привести к зависанию системы или даже стать причиной уязвимости к ReDoS-ата…
Обзор нововведений в C# 11

Дата: 21 Окт 2022

Автор: Константин Волоховский

C# 11 выходит уже совсем скоро, так что пора детально изучить новые особенности, которые появятся в языке. И хотя их немного, среди них есть довольно интересные: обобщённая математика, исходные строк…
Особенности реализации List в C#

Дата: 04 Окт 2022

Автор: Артём Ровенский

List является одной из самых популярных коллекций в C#. Давайте разберёмся в некоторых особенностях работы с ним и посмотрим на внутреннюю реализацию его отдельных частей.
Разбор ошибок в игровом движке Stride

Дата: 30 Сен 2022

Автор: Андрей Москалёв

Stride – это мощный, бесплатный и активно развивающийся игровой движок, реализованный на C#. Он вполне может стать альтернативой Unity, но насколько качественный исходный код Stride? Узнаем это с пом…

Комментарии (0)

Следующие комментарии
Unicorn with delicious cookie
Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо