Skip to content

[BUG] Unexpected Null-Forgiving Operators #2805

@madbranch

Description

@madbranch

Describe the bug
Since version 14.1.1, it looks like we are forced to add a lot of unnecessary ! and ? when nullable reference types are enabled.

Steps To Reproduce
Here is an example of what we have to do to get a view model to compile and expose properties as non-null:

using ReactiveUI;

namespace Example
{
  public class SomeViewModel : ReactiveObject
  {
    public SomeViewModel()
    {
      m_MyCombinedText = this
        .WhenAnyValue(vm => vm.MyFirstText,
                      vm => vm.MySecondText,
                      (first, second) => first! + second!)
        .ToProperty(this, x => x.MyCombinedText);
    }

    public string MyFirstText
    {
      get => m_MyFirstText;
      set => this.RaiseAndSetIfChanged(ref m_MyFirstText, value);
    }

    public string MySecondText
    {
      get => m_MySecondText;
      set => this.RaiseAndSetIfChanged(ref m_MySecondText, value);
    }

    public string MyCombinedText => m_MyCombinedText.Value!;

    private string m_MyFirstText = string.Empty;
    private string m_MySecondText = string.Empty;
    private readonly ObservableAsPropertyHelper<string?> m_MyCombinedText;
  }
}
  • WhenAnyValue's third parameter implementation shouldn't need the two !.
  • The MyCombinedText property getter shouldn't need that !.
  • The m_MyCombinedText private field type shouldn't need that ?.

Expected behavior
I would expect to be able to write the same SomeViewModel this way (still with nullable reference types enabled):

using ReactiveUI;

namespace Example
{
  public class SomeViewModel : ReactiveObject
  {
    public SomeViewModel()
    {
      m_MyCombinedText = this
        .WhenAnyValue(vm => vm.MyFirstText,
                      vm => vm.MySecondText,
                      (first, second) => first + second)
        .ToProperty(this, x => x.MyCombinedText);
    }

    public string MyFirstText
    {
      get => m_MyFirstText;
      set => this.RaiseAndSetIfChanged(ref m_MyFirstText, value);
    }

    public string MySecondText
    {
      get => m_MySecondText;
      set => this.RaiseAndSetIfChanged(ref m_MySecondText, value);
    }

    public string MyCombinedText => m_MyCombinedText.Value;

    private string m_MyFirstText = string.Empty;
    private string m_MySecondText = string.Empty;
    private readonly ObservableAsPropertyHelper<string> m_MyCombinedText;
  }
}

Environment

  • OS: Windows
  • Version 10
  • Device: PC
  • ReactiveUI 14.1.1

Additional context
The expected behavior used to work before 14.1.1. It seems to be related ot #2759

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions