Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
5 / 3 / 2
Регистрация: 27.04.2022
Сообщений: 60

Взаимные зависимости полей класса

19.04.2025, 09:11. Показов 1807. Ответов 13
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день!

Имеется необходимость, чтобы поля класса зависели друг от друга. То есть, чтобы при изменении какого-нибудь одного поля, остальные изменялись согласно определённым формулам. Насколько правильно использовать для этого следующий код?

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class SomeClass
{
    private double _property1;
    private double _property2;
    private double _property3;
 
    public double Property1
    {
        get { return _property1; }
        set 
        { 
            _property1 = value;
            _property2 = _property3 / _property1;
            _property3 = _property1 * _property2;
        }
    }
    public double Property2
    {
        get { return _property2; }
        set
        {
            _property2 = value;
            _property1 = _property3 / _property2;
            _property3 = _property1 * _property2;
        }
    }
    public double Property3
    {
        get { return _property3; }
        set
        {
            _property3 = value;
            _property1 = _property3 / _property2;
            _property2 = _property3 / _property1;
        }
    }
}
Или же для подобных задач используются другие подходы и инструменты?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
19.04.2025, 09:11
Ответы с готовыми решениями:

Сериализация объектов, имеющих взаимные ссылки
Подскажите, пожалуйста, как правильно сериализовывать/десериализовывать объекты, имеющие взаимные...

Вывод в DataGridView полей некоторого экземпляра класса, в котором одно из полей является списком List
Здравствуйте, помогите плиз!!! Возникла потребность вывода в DataGridView полей некоторого...

Реализация generic класса и метода(в зависимости от передаваемого типа(другого класса)
Задание: Создать generic класс что позволяет в зависимости переданного типа (другого класса)...

13
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16115 / 11236 / 2887
Регистрация: 21.04.2018
Сообщений: 33,036
Записей в блоге: 2
19.04.2025, 11:17
Цитата Сообщение от power_factor Посмотреть сообщение
Насколько правильно использовать для этого следующий код?
На первый взгляд - не правильно.
Но ошибка не в "программировании", а в математической логике.

Например:
C#
30
31
32
33
34
35
        set
        {
            _property3 = value;
            _property1 = _property3 / _property2;
            _property2 = _property3 / _property1; // Эта строка точно бессмыслена
        }
0
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3383 / 2697 / 573
Регистрация: 04.09.2018
Сообщений: 8,506
Записей в блоге: 3
19.04.2025, 11:35
power_factor, тут StackOverflow напрашивается... Сплошные рекурсивные установки свойств..
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16115 / 11236 / 2887
Регистрация: 21.04.2018
Сообщений: 33,036
Записей в блоге: 2
19.04.2025, 11:53
Цитата Сообщение от power_factor Посмотреть сообщение
Или же для подобных задач используются другие подходы и инструменты?
Если для "маленького" класса - то норм.
Если что-то большое, то обычно логику зависимости выносят из тела свойств.

В очень упрощённом виде:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    public class SomeClass
    {
        private double _property1;
        private double _property2;
        private double _property3;
 
        public double Property1 { get => _property1; set => Set(ref _property1, value); }
        public double Property2 { get => _property2; set => Set(ref _property2, value); }
        public double Property3 { get => _property3; set => Set(ref _property3, value); }
 
        private void Set(ref double field, double value, [CallerMemberName] string? propertyName = null)
        {
            double oldValue = field;
            field = value;
            switch (propertyName)
            {
                case nameof(_property1):
                    _property2 = _property3 / _property1;
                    break;
                case nameof(_property2):
                    _property1 = _property3 / _property2;
                    break;
                case nameof(_property3):
                    _property1 = _property3 / _property2;
                    break;
                default:
                    break;
            }
        }
    }
Цитата Сообщение от wizard41 Посмотреть сообщение
StackOverflow напрашивается... Сплошные рекурсивные установки свойств..
Устанавливаются не свойства, а поля.
Рекурсии нет.
0
2279 / 1596 / 399
Регистрация: 26.06.2017
Сообщений: 4,719
Записей в блоге: 1
19.04.2025, 11:53
Цитата Сообщение от wizard41 Посмотреть сообщение
Сплошные рекурсивные установки свойств..
Нету этого, т.к. в сеттерах работа с приватными полями.
0
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3383 / 2697 / 573
Регистрация: 04.09.2018
Сообщений: 8,506
Записей в блоге: 3
19.04.2025, 12:31
Ааа, мельком глянул. Все равно хрень полная написана..
0
Эксперт .NET
 Аватар для Wolfdp
3785 / 1762 / 371
Регистрация: 15.06.2012
Сообщений: 6,535
Записей в блоге: 3
19.04.2025, 17:02
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Но ошибка не в "программировании", а в математической логике.
Замечание верное: у нас неочевидная зависимость от изменяемого значения, и как это должно афектить остальные. Например можно записать так

C#
1
2
3
4
5
(_property1, _property2) = (1, 2)
 
_property3 = value; // допустим 10
_property1 = _property3 / _property2; // = 5
_property2 = _property3 / _property1; // = 2
а можно так (поменяли местами очередность)

C#
1
2
3
_property3 = value; // тоже 10
_property2 = _property3 / _property1; // = 10
_property1 = _property3 / _property2; // = 1
вообще тут явная кольцевая зависимость, а это зло априори. Нужен контекст и понимание на кой это делается.
1
5 / 3 / 2
Регистрация: 27.04.2022
Сообщений: 60
20.04.2025, 03:43  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Если для "маленького" класса - то норм.
Оно хоть и работает, но, есть подозрения, что в дальнейшем может преподнести неожиданные сюрпризы в виде какого-нибудь непредсказуемого поведения. Да и "маленький" класс со временем может трансформироваться в какого-нибудь монстра. Мне казалось, что для профессионального программирования это тривиальная задача с типовым решением.

Цитата Сообщение от Wolfdp Посмотреть сообщение
Нужен контекст и понимание на кой это делается.
Например, сохранение пропорций 3D фигуры. Есть три параметра: высота, ширина и длина. При изменении одного из них, два других также должны измениться.

Не по теме:


Цитата Сообщение от wizard41 Посмотреть сообщение
Все равно хрень полная написана..
Ну дык сюда и заходят, чтобы поинтересоваться у опытных людей как написать не хрень)

0
Эксперт .NET
 Аватар для Wolfdp
3785 / 1762 / 371
Регистрация: 15.06.2012
Сообщений: 6,535
Записей в блоге: 3
20.04.2025, 03:54
Цитата Сообщение от power_factor Посмотреть сообщение
Например, сохранение пропорций 3D фигуры. Есть три параметра: высота, ширина и длина. При изменении одного из них, два других также должны измениться.
Дык, нужно же высчитывать коффециент изменения и умножать на него все остальные значения. Т.е. поменяли высоту с 10 на 15. Кофециент 1.5, множим всё остальное. Тут нет взаимо-зависимости.
0
5 / 3 / 2
Регистрация: 27.04.2022
Сообщений: 60
20.04.2025, 06:28  [ТС]
Цитата Сообщение от Wolfdp Посмотреть сообщение
Дык, нужно же высчитывать коффециент изменения и умножать на него все остальные значения. Т.е. поменяли высоту с 10 на 15. Кофециент 1.5, множим всё остальное. Тут нет взаимо-зависимости.
Так вот можем ли мы это всё множить в блоке сеттера высоты, которая поменялась?
C#
1
2
3
4
5
6
7
8
9
10
11
        // представим, что мы где-то определили коэффициент изменения = 1.5
        public double Height
        {
            get { return _height; }
            set 
            { 
                _height = value;
                _lenght = _height * 1.5;
                _width = _height * 1.5;
            }
        }
Такой подход работает, но нигде в документации или на форумах не видел, чтобы так делали. Стало быть, есть какие-то подводные камни.

Вопрос не в конкретном примере (это может быть какое-то электрооборудование, в котором ток, мощность и сопротивление зависят друг от друга; либо системы регулирования с несколькими параметрами). Вопрос в концепции. Возможно, более правильно это всё делать через обработку событий или ещё как-то?
0
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3383 / 2697 / 573
Регистрация: 04.09.2018
Сообщений: 8,506
Записей в блоге: 3
20.04.2025, 09:28
Цитата Сообщение от power_factor Посмотреть сообщение
либо системы регулирования с несколькими параметрами
Обычно это методы принимающие все необходимые аргументы (параметры) для очередного вычисления. Если в процессе этого изменяются какие-л. зависимые свойства, то они меняются этим методом (свойства с приватным set).

Тут скорее вопрос не в том "правильно/неправильно", а в том, на сколько это будет удобно и не вызовет ли неочевидных проблем, например, если действительно в установках полей что-то случайно поменять местами.

Если свойств всего три (как здесь), то еще терпит, а если их будет 10... Замучаешься прыгать по ним и вычислять последовательность - кто что и когда меняет.

Цитата Сообщение от power_factor Посмотреть сообщение
Например, сохранение пропорций 3D фигуры. Есть три параметра: высота, ширина и длина.
Не проще ли установку этих всех параметров производить через один метод, который сам всем свойствам назначит новые значения?
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16115 / 11236 / 2887
Регистрация: 21.04.2018
Сообщений: 33,036
Записей в блоге: 2
20.04.2025, 11:37
Цитата Сообщение от power_factor Посмотреть сообщение
Мне казалось, что для профессионального программирования это тривиальная задача с типовым решением.
Я же дал вам вариант, как обычно это делается.
Через внешний (по отношению к свойству) метод создающий зависимости.

Добавлено через 7 минут
Цитата Сообщение от power_factor Посмотреть сообщение
Вопрос не в конкретном примере (это может быть какое-то электрооборудование, в котором ток, мощность и сопротивление зависят друг от друга; либо системы регулирования с несколькими параметрами). Вопрос в концепции. Возможно, более правильно это всё делать через обработку событий или ещё как-то?
power_factor, wizard41 вам пишет (и я ранее написал) за ошибку в МАТЕМАТИЧЕКОЙ логике.

У вас есть МАТЕМАТИЧЕСКОЕ уравнение связывающее три параметра _property3 = _property1 * _property2;.
Это ОДНО уравнение. И по правилам математики, в нём может быть только ОДНО неизвестное.
А в каждом сеттере устанавливается ДВА свойство, то есть ДВЕ неизвестные.
В моём варианте с внешним методом, я показал правильную логику.
0
Эксперт .NET
 Аватар для Wolfdp
3785 / 1762 / 371
Регистрация: 15.06.2012
Сообщений: 6,535
Записей в блоге: 3
20.04.2025, 18:20
1. Я бы делал отдельным методом, чтобы было понимание что происходит, и оставалась возможность просто задать нужное значение без правок остальных.

2. кофециент считается на основе старого значения и нового.

C#
1
2
3
4
5
6
7
8
9
10
11
12
public double Height 
{
  get => _height;
  set => _height = value;
}
 
public void SyncChangeByHeight(double height)
{
  var k = height / _height;
  _width *= k;
  _length *= k;
}
Добавлено через 3 минуты
Цитата Сообщение от power_factor Посмотреть сообщение
Вопрос в концепции.
отдельный метод.

Свойства обычно подразумевают что set меняет только конкретное свойство, а не запускает цепочку изменений по всему объекту.
1
Эксперт JavaЭксперт по электроникеЭксперт .NET
 Аватар для wizard41
3383 / 2697 / 573
Регистрация: 04.09.2018
Сообщений: 8,506
Записей в блоге: 3
20.04.2025, 23:15
Христос Воскресе!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
20.04.2025, 23:15
Помогаю со студенческими работами здесь

Клиент-сервер: Оповещение о событии других классов в зависимости от значения одного из полей
Есть пустыня. В пустыне есть область, где можно добывать полезные ископаемые. Вдалеке от этой...

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

Ошибка при инициализации полей класса
Помогите найти ошибку. Делаю игру 21. Инициализирую массив классов значениями. Но вылетает ошибка....

Сериализация закрытых (private) полей класса
Я пишу свой сериализатор/десериализатор, НЕ на основе System.XML.Serialization. (Я бы и не взялся...

Как достучатся до полей и методов наследника абстрактного класса?
Начал писать игру "бомбермен". Создал абстрактный класс Ячейка (abstract class Cell). От ячейки...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru