Cysharp / R3

The new future of dotnet/reactive and UniRx.
MIT License
1.72k stars 70 forks source link

ObservePropertyChanged is not working on VS2019 #180

Closed eagle628 closed 3 months ago

eagle628 commented 3 months ago

Hi.

I am wondering about the extension method of ObservePropertyChanged.

The following code is under VS2019 environment, the extended method of ObservePropertyChanged is a runtime error (System.ArgumentNullException). FromEvent, which can achieve something similar, does not result in a runtime error.

Incidentally, the Pairwise Operator had nothing to do with this. It is left as is for display purposes.

Please let me know if there is a problem with the code you are implementing, and as long as it works in VS2022, it probably is...

Environment: Net Framework 4.7.2 for both VS2019 and VS2022.

class Program
{
    static void Main(string[] args)
    {
        var p = new Person();

        var d0 = p
            .ObservePropertyChanged(x => x.Name)
            .Pairwise()
            .Subscribe(pair => Console.WriteLine($"ObservePropertyChanged : from {pair.Previous} to {pair.Current}"));

        var d1 = Observable
            .FromEvent<PropertyChangedEventHandler, PropertyChangedEventArgs>(
                h => (s, e) => h(e),
                h => p.PropertyChanged += h,
                h => p.PropertyChanged -= h)
            .Where(arg => arg.PropertyName == nameof(Person.Name))
            .Select(_ => p.Name)
            .Pairwise()
            .Subscribe(pair => Console.WriteLine($"FromEvent : from {pair.Previous} to {pair.Current}"));

        p.Name = "temp0";
        p.Name = "temp1";
        p.Name = "temp2";

        d0.Dispose();
        d1.Dispose();

        Console.ReadLine();
    }
}
class Person : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged([CallerMemberName] string name = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }
    private string _name;
    public string Name
    {
        get => _name;
        set
        {
            if (_name != value)
            {
                _name = value;
                OnPropertyChanged();
            }
        }
    }
    public Person()
    {
        _name = string.Empty;
    }
}
neuecc commented 3 months ago

Please provide more details(error message, stacktrace, etc) on runtime errors.

However, I think it is probably affected by the CallerArgumentExpressionAttribute that ObservePropertyChanged is using. Since CallerArgumentExpressionAttribute has been available since C# 10.0, please explicitly set the LangVersion to csproj and try it.

eagle628 commented 3 months ago

Thanks for your response.

StackTrace is here.

System.ArgumentNullException
  HResult=0x80004003
  Message=値を Null にすることはできません。
  Source=R3
  スタック トレース:
   場所 R3.Observable.ObservePropertyChanged[T,TProperty](T value, Func`2 propertySelector, Boolean pushCurrentValueOnSubscribe, CancellationToken cancellationToken, String expr)
   場所 SampleR3OnVs2019.Program.Main(String[] args) (SampleR3OnVs2019\SampleR3OnVs2019\Program.cs):行 18

There seems to be some problem with CarelArgumentExpressionAttribute as you indicated. (When I try to confirm R3-main\src\R3\Factories\ObserveProperty.cs, args null check is exited in this library. )

I tried to specify the language version explicitly, but it seems that C# 10.0 is not available for .Net Framework 4.7.2. Actually, the official documentation says, "C# 10 is supported only on .NET 6 and newer versions." OfficialLink

However, with .Net Framework 4.7.2 On VS2022, the first implementation works fine. In fact, the language version is C# 7.3.

So I think the language version on the user application side is irrelevant.

I also compared the cspoj files just to be sure, but I don't think there is any difference.

neuecc commented 3 months ago

The combination of C# version and .NET Framework version can be changed. However, it seems that VS2019 only supports up to C# 9 in the first place. Therefore, it is impossible to run it in VS2019.

eagle628 commented 3 months ago

I understand that VS2020 can intepret CallerArgumentExpressionAttribute on c# 7.3 of user app but VS2019 cannot.

In my work, I can only use VS2019, so I will substitute FromEvent, etc. Thanks for your response!