dotnet icon indicating copy to clipboard operation
dotnet copied to clipboard

newValue argument as Ref for *Changing() generated methods

Open Gabboxl opened this issue 1 year ago • 1 comments

Overview

Hi, I'm migrating some old C# ViewModel code to use the [ObservableProperty] attribute on all the properties.

I'd like to convert the following code:

private string _windowTitle;
public string WindowTitle {
  get {
    return _windowTitle;
  }
  set {
    _windowTitle = $ "Window title prefix: {value}";
    OnPropertyChanged(nameof(WindowTitle));
  }
}

...but I couldn't find any "simple" or "standard" method to accomplish the same behavior using the MVVM Toolkit.

I discovered that recently the methods *Changing(string? newValue) or *Changing(string? oldValue, string newValue) got added, but the newValue isn't passed as ref string, so I can't intercept and change the value.

Could this prototype be implemented for those methods? Thanks!

API breakdown

partial void OnWindowTitleChanging(ref string value);
partial void OnWindowTitleChanging(string? oldValue, ref string newValue);

Usage example

partial void OnWindowTitleChanging(string? oldValue, ref string newValue)
{
    newValue = "Window title prefix: " + newValue;
}

Breaking change?

I'm not sure

Alternatives

Additional context

No response

Help us help you

No, just wanted to propose this

Gabboxl avatar Feb 25 '25 14:02 Gabboxl

Changing the existing partial methods to always be a ref would definitely be a breaking change. But I'm curious as to whether or not the generator can simply change the partial signatures of those methods if it sees an implementation that takes a ref parameter. If it can do that (I think it probably can since it adapts the generated property based on whether the partial void methods are implemented), then that should take care of any breaking changes.

If not, then a simple way to avoid it is to have the source generator insert a call to something like InterceptWindowTitleChange(ref interceptedValue) and then set the backing field to that as well as pass that in to the *Changed methods afterward.

So everything after the *Changing methods would become something like the following if InterceptWindowTitleChange were implemented:

string interceptedValue = value;

InterceptWindowTitleChange(ref interceptedValue);

_windowTitle = interceptedValue;

OnWindowTitleChanged(interceptedValue);
OnWindowTitleChanged(default, interceptedValue);

bzd3y avatar Apr 10 '25 17:04 bzd3y