Обновление свойства объекта на основе других свойств

Я пытаюсь обновить свойство на основе значения двух других свойств.

Я использую INotifyPropertyChanged здесь.

Итак, в основном у меня есть 3 свойства A, B и C. Свойство, которое я обновляю, находится здесь C на основе A и B. Я могу обновить значение свойства C из A и B. Таким образом, свойство C будет добавлением свойств A и B (C = A + B). Он отлично работает, когда одно значение передается либо из A, либо из B, но когда передаются значения из обоих свойств, оно принимает значение только из последнего переданного значения свойства. Я знаю, что мне нужно увеличивать значение C при передаче значения из каждого свойства. Но как лучше всего этого добиться?

Вот мой код:

private int? _a;
public int? A
{
   get => _a;
   set
   {
       _a = value;
       OnPropertyChanged($"A");
       C = _a;
   }
 }

private int? _b;
public int? B
{
    get => _b;
    set
    {
       _b = value;
       OnPropertyChanged($"B");
       C = _b;
    }
 }

 private int? _c;
 public int? C
 {
    get => _c;
    set
    {
       _c = value;
    }
 }

 public event PropertyChangedEventHandler PropertyChanged;

 [NotifyPropertyChangedInvocator]
 protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
 {
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
 }

Обновлять

Извините за путаницу выше, в основном я пытаюсь обновить значение свойства C, когда свойства A и B передаются. Таким образом, свойство C будет добавлением свойств A и B (C = A + B). Надеюсь, это устранит путаницу?

Если вы присвоите x ряд значений, x всегда будет иметь последнее назначенное значение. C должен быть рассчитан или что-то в этом роде? Вы говорите: «Я знаю, что мне нужно увеличивать значение C при передаче значения из каждого свойства». -- затем напишите код, который будет увеличивать значение C "при передаче значения из каждого свойства" (мы не можем помочь вам с этой частью в кавычках, потому что мы не знаем, что это значит). Какие бы вычисления ни выполнялись для определения значения C, когда C необходимо обновить, выполняйте их каждый раз, когда результат этих вычислений изменится.

15ee8f99-57ff-4f92-890c-b56153 28.05.2019 18:02

Ваш пример кода не имеет никакого смысла. C ВСЕГДА является значением A или B (в зависимости от того, что было обновлено последним). Что вы хотите с этим делать?

Steve Todd 28.05.2019 18:02

Например, если C всегда должен быть суммой A и B, то в установщиках для A и Б, обоих из них, добавьте следующее: C = A + B; Если это произведение, C = A * B; И установщик C должен вызвать OnPropertyChanged("C");

15ee8f99-57ff-4f92-890c-b56153 28.05.2019 18:04

Извините за путаницу, ребята, конечным результатом является обновление значения C на основе значений как из A, так и из B.

KJSR 28.05.2019 18:04

«На основе значений как A, так и B»… что означает «на основе»? Добавлять? вычесть? умножить?

JuanR 28.05.2019 18:05

@JuanR Да добавлены значения A и B

KJSR 28.05.2019 18:07

@Kevin Пожалуйста, обновите свой вопрос, чтобы в нем говорилось, что вы на самом деле пытаетесь сделать.

15ee8f99-57ff-4f92-890c-b56153 28.05.2019 18:08

Разве вы не можете просто получить C собственность return _a + _b? Цель (или проблема) до сих пор не ясна.

JuanR 28.05.2019 18:08
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
8
534
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Учитывая приведенное выше пояснение, вы бы сделали что-то вроде:

private int? _a;
public int? A
{
   get => _a;
   set
   {
       if (value.HasValue != _a.HasValue || value.GetValueOrDefault(0) != _a.GetValueOrDefault(0))
       {
          _a = value;
          OnPropertyChanged();
          OnPropertyChanged(nameof(C));
       }
   }
 }

private int? _b;
public int? B
{
    get => _b;
    set
    {
       if (value.HasValue != _b.HasValue || value.GetValueOrDefault(0) != _b.GetValueOrDefault(0))
       {
          _a = value;
          OnPropertyChanged();
          OnPropertyChanged(nameof(C));
       }
    }
 }

 public int? C
 {
    get => A + B;
 }

 public event PropertyChangedEventHandler PropertyChanged;

 [NotifyPropertyChangedInvocator]
 protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
 {
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
 }

Или используйте OnPropertyChanged(nameof(C));

stuartd 28.05.2019 18:31

Это, безусловно, делает код чище (и упрощает рефакторинг).

Steve Todd 28.05.2019 18:32

@stuartd просто опередил меня :)

KJSR 28.05.2019 18:32

Спасибо @SteveTodd за решение. Это имеет так много смысла сейчас. Я запутался в том, где на самом деле вызывать событие OnPropertyChanged?! Думаю, нужно вернуться и прочитать больше о INotifyPropertyChanged. Также спасибо @Ed Plunkett за помощь в прояснении вопроса :)

KJSR 28.05.2019 18:35

@Kevin Вы просто хотите убедиться, что OnPropertyChanged(nameof(C)) вызывается всякий раз, когда значение C изменяется. Итак, выясните, что вызывает изменение значения C, и поместите его туда. Если у C есть установщик, вызовите OnPropertyChanged(nameof(C)) в установщике внутри оператора if, который показал вам Стив (и никогда не устанавливайте _c вне этого установщика). Если C => A + B;, то установщики A и B изменят значение C, поэтому вы хотите поместить OnPropertyChanged(nameof(C)) в оба этих установщика.

15ee8f99-57ff-4f92-890c-b56153 28.05.2019 18:40

@Ed, подсказка параметра [CallerMemberName] в OnPropertyChanged автоматически заполняет имя функции/свойства, вызвавшее изменение, поэтому установщику для C (если он существует) не нужен бит nameof (вы, вероятно, знаете это, но для OP выгода).

Steve Todd 28.05.2019 18:46

Почему свойства дважды вызывают OnPropertyChanged и есть ли причина использовать геттеры для A и B, когда базовые свойства доступны внутри?

JuanR 28.05.2019 19:49

@JuanR, считается плохой практикой прямой доступ к резервной переменной где-то, кроме ее геттера и сеттера. Что, если изменить код, чтобы инициировать другие действия при чтении или изменении значения? Два вызова должны сначала сказать, что «это свойство изменилось», а затем «это другое свойство, которое зависит от этого значения, также должно быть изменено».

Steve Todd 29.05.2019 11:58

@SteveTodd: я могу понять, считается ли это «плохой практикой», но я с уважением не согласен с этим. Класс выполняет внутренние операции, поэтому, по крайней мере, для меня он должен работать с резервным полем, а не с оболочкой, но это только мое предпочтение. Я не знаю о двойных звонках OnPropertyChanged. Я понимаю, почему, но для меня это своего рода запах кода, когда свойство отвечает за инициирование событий для какого-то другого свойства. Возможно, C должен быть методом?

JuanR 29.05.2019 15:37

@JuanR, что, если вы хотите привязать вычисленный результат к своей форме? Форма должна знать, что она изменилась, и она должна быть чем-то, что можно связать.

Steve Todd 29.05.2019 17:45

@SteveTodd: я думаю, что потребности вашей формы (GUI) не должны иметь никакого отношения к дизайну вашего класса. В любом случае, давайте не будем загрязнять этот ответ философскими разногласиями. Мы представили ОП разные точки зрения. Ему решать. :-)

JuanR 29.05.2019 17:54

Другие вопросы по теме