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

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

![0996_NRE_MAUI_ru/image1.png](https://import.viva64.com/docx/blog/0996_NRE_MAUI_ru/image1.png)

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

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

Код создаёт впечатление, что авторы очень торопятся при его написании\. Из\-за этого во многих местах без проверок разыменовываются ссылки, которые, по мнению самих же разработчиков, могут быть нулевыми\. Чтобы было понятнее, давайте взглянем на отдельные фрагменты из [исходников](https://github.com/dotnet/maui/releases/tag/6.0.424) MAUI 6\.0\.424\.

## Почему так?

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

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

```cpp
void AttachEvents()
{
  ....

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

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

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

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

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

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

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

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

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

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

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

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

```cpp
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\. А в целом желаю им успехов с развитием проекта\.