Использование оператора нуль-условных чисел в левой части присваивания

У меня есть несколько страниц, каждый из которых имеет свойство с именем Data. На другой странице я устанавливаю эти данные следующим образом:

if (MyPage1 != null)
    MyPage1.Data = this.data;
if (MyPage2 != null)
    MyPage2.Data = this.data;
if (MyPage3 != null)
    MyPage3.Data = this.data;

Есть ли возможность использовать нуль-условный оператор на MyPage? Я думаю о чем-то вроде этого:

MyPage?.Data = this.data;

Но когда я пишу это так, я получаю следующую ошибку:

Левая часть присваивания должна быть переменной, свойством или индексом.

Я знаю это, потому что MyPage может быть нулевым, а левая сторона больше не будет переменной.

Не то, чтобы я не мог использовать его, как я уже это делал, но я просто хочу знать, есть ли возможность использовать на нем оператор с нулевым условием.

Ответы

Ответ 1

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

Конечно, вы могли бы сделать вещи короче, используя оператор tenary, но это, с другой стороны, не очень помогает аспекту читаемости.

Комментарий Йоахима Исакссона по вашему вопросу показывает другой подход, который должен работать.

Ответ 2

Как предложил Joachim Isaksson в комментариях, теперь у меня есть метод SetData(Data data) и используйте его следующим образом:

MyPage1?.SetData(this.data);
MyPage2?.SetData(this.data);
MyPage3?.SetData(this.data);

Ответ 3

Попробуйте это Добавьте все свои страницы в myPageList.

IEnumerable<MyPage> myPageList;

foreach(MyPage myPage in myPageList)
{
if (myPage != null)
    myPage.Data = this.data;
}

Ответ 4

Я придумал следующее расширение,

public static class ObjectExtensions
{
    public static void SetValue<TValue>(this object @object, string propertyName, TValue value)
    {
        var property = @object.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance);
        if (property?.CanWrite == true)
            property.SetValue(@object, value, null);
    }
}

Что можно назвать глобально; это работает только в общественных свойствах.

myObject?.SetValue("MyProperty", new SomeObject());

Следующая улучшенная версия работает на что угодно,

public static void SetValue<TObject>(this TObject @object, Action<TObject> assignment)
{
    assignment(@object);
}

И также можно назвать глобально,

myObject?.SetValue(i => i.MyProperty = new SomeObject());

Но имя расширения несколько вводит в заблуждение, поскольку Action не требует исключительно назначения.

Ответ 5

Общий метод расширения SetValue (но только для свойств ref) будет:

    public static void SetValue<T>(this T property, T value)
    {
        property = value;
    }

И будет использоваться как

ButtonOrNull?.Visibility.SetValue(Visibility.Hidden);