Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.50/4: Рейтинг темы: голосов - 4, средняя оценка - 4.50
9 / 6 / 3
Регистрация: 10.01.2020
Сообщений: 330
.NET 4.x

Обновлять ссылочный объект принятый через конструктор

04.02.2023, 12:21. Показов 1167. Ответов 20
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый всем!
Не знаю как правильно сформулировать, покажу на примере.

Есть 2 класса
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
internal class One
{
    public One(string name)
    {
        Name = name;
    }
    public string Name { get; set; }
}
 
internal class Two
{
    public Two(One one)
    {
        One = one;
    }
    public One One { get; }
    public string Some { get; }
}
Создаём объекты
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
var one = new One("One");
var two = new Two(one);
 
 
// Объекты будут равны
if (two.One.Name == one.Name)
{
    Console.WriteLine("Равны");
}
 
if (two.One.Equals(one))
{
    log.Info($"Равны");
}
 
// Если установить 
one.Name = "OneOne";
 
// Тоже всё будет равно
if (two.One.Name == one.Name)
{
    Console.WriteLine("Равны");
}
 
if (two.One.Equals(one))
{
    log.Info($"Равны");
}
Но если пересоздать объект one, то в объекте two останется старый экземпляр.
C#
1
2
3
4
5
6
7
8
9
10
one = new One("OneOneOne");
 
if (two.One.Equals(one))
{
 
}
else
{
    Console.WriteLine("Не равны");
}

Как сделать так, чтобы при пересоздании one внутри two так же был новый объект?
Без необходимости передачи one в two.Update(one) или без пересоздания самого two = new Two(one)?


Может можно сделать как-то, чтобы класс Two следил за этим, и при пересоздании, обновлял объект на новый?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
04.02.2023, 12:21
Ответы с готовыми решениями:

Как инициализировать указатель на объект через конструктор?
Имеется код int main(void) { SetConsoleCP(1251); SetConsoleOutputCP(1251); char F, I, O;

Как передать объект ArrayList через конструктор
Здравствуйте. Переписываю курсовую с C# на CLI . Столкнулся со следующей проблемой. На С# я передавал список с помощью ref. ...

Как передать объект (при его создании через конструктор) в массив? C++
Создал класс и динамический массив: class flight { public: flight(); string info(); private: string destination =...

20
 Аватар для IamRain
4694 / 2702 / 734
Регистрация: 02.08.2011
Сообщений: 7,233
04.02.2023, 12:32
Цитата Сообщение от BeginnerCoderCS Посмотреть сообщение
Может можно сделать как-то, чтобы класс Two следил за этим, и при пересоздании, обновлял объект на новый?
Агрегат не должен следить за своими зависимостями другими возможными ссылками на свою зависимость. Он просто сохранил ссылку на объект и пользуется объектом по этой ссылке.
Для чего это понадобилось?
0
9 / 6 / 3
Регистрация: 10.01.2020
Сообщений: 330
04.02.2023, 12:42  [ТС]
Цитата Сообщение от IamRain Посмотреть сообщение
Для чего это понадобилось?
Моя программа работает "в рамках другой программы", и там произошли изменения, и один из объектов стал периодически обновляться.
Этот объект остаётся мусором, не подключённым к внешней программой.
Отследить создание объекта можно, но пересоздавать все классы, которые его используют нельзя, так как в них хранится много состояний и данных.
0
 Аватар для IamRain
4694 / 2702 / 734
Регистрация: 02.08.2011
Сообщений: 7,233
04.02.2023, 12:58
Цитата Сообщение от BeginnerCoderCS Посмотреть сообщение
Этот объект остаётся мусором, не подключённым к внешней программой.
Если есть возможность сделать общие объекты Singletone-ами, я бы так и сделал.
И в Two.One сохранял бы ссылку на синглтон. Никогда его не пересоздавая, разумеется.

Добавлено через 3 минуты
Цитата Сообщение от BeginnerCoderCS Посмотреть сообщение
Без необходимости передачи one в two.Update(one)
А так почему нельзя делать?

Добавлено через 8 минут
По-хорошему уведомления делаются через события, и в классе-подписчике можно обновлять ссылку, указывая на вновь созданный объект.
Но выглядит это как неоптимальный костыльный хак. Просто ненужные/нерациональные затраты процессорного времени для решения проблемы.
1
9 / 6 / 3
Регистрация: 10.01.2020
Сообщений: 330
04.02.2023, 13:13  [ТС]
Цитата Сообщение от IamRain Посмотреть сообщение
Если есть возможность сделать общие объекты Singletone-ами, я бы так и сделал.
И в Two.One сохранял бы ссылку на синглтон. Никогда его не пересоздавая, разумеется.
Что-то не пойму (

На примере кода выше.
`one` я не могу никак сделать синглтоном, так как не имею к этому доступа.

Класс One это и есть класс внешней программы, я не создаю объект `one`, мне его предоставляет уже готовым программа.

Класс Two это уже мой.

Но в классе Two ещё создаются Three и Four и в них тоже попадает этот объект `one` через конструктор.
Это по сути и является ответом на
Цитата Сообщение от IamRain Посмотреть сообщение
А так почему нельзя делать?

Есть мысль но не знаю как реализовать.
Допустим при изменении `one` я обновлю в Two `two.Update(one)`, но как сделать так, чтобы остальные Three и Four отследили обновление объекта в two после (`two.Update(one)`), и тоже обновились?

Добавлено через 11 минут
Цитата Сообщение от IamRain Посмотреть сообщение
По-хорошему уведомления делаются через события, и в классе-подписчике можно обновлять ссылку, указывая на вновь созданный объект.
Но выглядит это как неоптимальный костыльный хак. Просто ненужные/нерациональные затраты процессорного времени для решения проблемы.
Это слишком много ресурсов будет потреблять?
0
 Аватар для IamRain
4694 / 2702 / 734
Регистрация: 02.08.2011
Сообщений: 7,233
04.02.2023, 13:32
Цитата Сообщение от BeginnerCoderCS Посмотреть сообщение
но как сделать так, чтобы остальные Three и Four отследили обновление объекта
Ну блин, если Two - агрегат, где есть One, Three, Four, то если вы можете добавить метод:
C#
1
2
3
4
5
6
7
8
9
10
internal void TryUpdateRef(One possiblyNewObject)
{
   if (Object.ReferenceEquals(this.One, possiblyNewObject))
        return;         
              
        this.One = possiblyNewObject;
       // прямо тут же и обновляем
        this.Three.UpdateDependencyRef(possiblyNewObject);
        this.Four.UpdateDependencyRef(possiblyNewObject);
}
Добавлено через 1 минуту
Вызывать метод перед другим критичным поведением, то есть там, где важно иметь актуальную версию.

Добавлено через 14 минут
можно прямо объявить нашу внутреннюю кухню с костылями и никому ее не показывать (internal):
C#
1
2
3
4
5
6
internal interface IDependencyRefUpdater<T> where T : class
{
   bool TryUpdateDependencyRef(T dependency);
   
   void UpdateDependencyRef(T dependency);
}
И реализовать этот интерфейс в классах Two, Three, Four.
1
9 / 6 / 3
Регистрация: 10.01.2020
Сообщений: 330
04.02.2023, 13:54  [ТС]
IamRain, а под синглтоном вы не такое имели в виду?

C#
1
2
3
4
5
6
7
8
9
10
internal class Three
{
    public Three(Two two)
    {
        this.two = two;
    }
 
    private readonly Two two;
    private One One => two.One;
}
А в Two обновлять internal void TryUpdateRef(One possiblyNewObject)
0
 Аватар для IamRain
4694 / 2702 / 734
Регистрация: 02.08.2011
Сообщений: 7,233
04.02.2023, 14:00
BeginnerCoderCS, синглтон - это строго один объект в приложении (паттерн проектирования - одиночка)
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class One
{
   private One() {} 
 
   static One() 
   {
        //без Lazy
        Instance = new();
   }
  
   public static One Instance { get; }
}
 
// и никто не сможет больше создать ни единого объекта этого типа
var obj = One.Instance;
0
 Аватар для Hront
23 / 16 / 7
Регистрация: 03.02.2023
Сообщений: 93
04.02.2023, 14:08
Вставлю свои пять копеек, может поможет
Может прозвучит глупо...
А сделать свой класс One one который будет отслеживать изменения и меняться сам, и пусть все остальные ссылаются уже на него. Тут можно будет уже и делегаты впихнуть и еще чего придумать...
Эдакую прослойку...

Добавлено через 1 минуту
У него я так понял нету доступа к классу One, только как результат.
1
9 / 6 / 3
Регистрация: 10.01.2020
Сообщений: 330
04.02.2023, 15:00  [ТС]
Цитата Сообщение от IamRain Посмотреть сообщение
синглтон - это строго один объект в приложении (паттерн проектирования - одиночка)
Это да, но выше писал, что у меня только есть объект one, при чём реализация закрыта.
То есть у меня вот такой объект IOne one, даже реализацию One не знаю. Есть методы что делает one и его интерфейс IOne.

Цитата Сообщение от Hront Посмотреть сообщение
А сделать свой класс One one который будет отслеживать изменения и меняться сам, и пусть все остальные ссылаются уже на него. Тут можно будет уже и делегаты впихнуть и еще чего придумать...
Эдакую прослойку...
Вот так имеете в виду?
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
38
39
40
41
42
/// Есть интерфейс (НЕ МОЙ)
public interface IOne
{
    string Name { get; }
}
 
/// Мой интерфейс с объектом в качестве свойства
internal interface IMyOne : IOne
{
    IOne One { get; }
    void Update(IOne one);
 
}
 
/// Реализация моего интерфейса с обновлением объекта
internal class MyOne : IMyOne
{
    public MyOne(IOne one)
    {
        One = one;
    }
    public IOne One { get; private set; }
 
    public string Name { get; private set; }
 
    public void Update(IOne one)
    {
        One = one;
    }
}
 
/// Класс который использует объект one 
internal class Four
{
    public Four(IMyOne myOne)
    {
        MyOne = myOne;
    }
 
    private readonly IMyOne MyOne;
    private IOne one => MyOne.One;
}
Если правильно понял, то вроде норм.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16140 / 11264 / 2888
Регистрация: 21.04.2018
Сообщений: 33,109
Записей в блоге: 2
04.02.2023, 15:28
Цитата Сообщение от BeginnerCoderCS Посмотреть сообщение
Отследить создание объекта можно,
Как именно вы можете отследить создание экземпляров One, если это тип из чужой библы в которую вы не можете вносить изменения и экземпляры эти могут создаваться где и кем угодно?

Вы или переоцениваете свои возможности по отслеживанию создания экземпляров, либо не предоставили существенную для решения вопроса информацию.
0
 Аватар для Hront
23 / 16 / 7
Регистрация: 03.02.2023
Сообщений: 93
04.02.2023, 15:36
Примерно так, только в каком месте идет отслеживание изменений в объекте IOne.
У вас есть метод Update(IOne one) но когда он должен срабатывать?
Если конечно оно есть "за кадром" то ладно
0
9 / 6 / 3
Регистрация: 10.01.2020
Сообщений: 330
04.02.2023, 16:22  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Как именно вы можете отследить создание экземпляров One, если это тип из чужой библы в которую вы не можете вносить изменения и экземпляры эти могут создаваться где и кем угодно?
Вы или переоцениваете свои возможности по отслеживанию создания экземпляров, либо не предоставили существенную для решения вопроса информацию.
Да, вы правы чуть недоговорил, конкретно момент создания объекта я не знаю, но там ещё есть один неизменяемый объект, в котором есть "dynamic контейнеры", в который я сохраняю свой объект one и потом сверяю reference one предоставленного с one в контейнере.

Если имели дело с контроллерами (esp, arduino) там setup и loop, то это похожая реализация.

Несколько объектов таких как one и container есть всегда, и меняться они в принципе не должны, но выходит что бывает и такое.
Только с помощью этого костыля с контейнером удалось понять почему оно не работает.


C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void setup()
{
    container["one"].SetValue(one);
    container["two"].SetValue(new Two(one));
}
 
 
void loop()
{
    if (ReferenceEquals(one, container["one"].Value))
    {
        container["two"].Value.UpdateOne(one);
    }
    
    var two = container["one"].Value;
    two.DoSomething();
}

p.s. Эта информация как по мне лишняя, так как создаст не ответы, а доп. вопросы, на которые я ответить не смогу даже при желании, поэтому и не говорил. Но теперь упрощённая модель есть )

Цитата Сообщение от Hront Посмотреть сообщение
У вас есть метод Update(IOne one) но когда он должен срабатывать?
Если конечно оно есть "за кадром" то ладно
Да был за кадром, уже кадр показал выше.
0
Эксперт .NET
 Аватар для Usaga
14303 / 9388 / 1354
Регистрация: 21.01.2016
Сообщений: 35,398
04.02.2023, 16:39
Цитата Сообщение от BeginnerCoderCS Посмотреть сообщение
Как сделать так, чтобы при пересоздании one внутри two так же был новый объект?
Без необходимости передачи one в two.Update(one) или без пересоздания самого two = new Two(one)?
Это очень фиговая практика, так делать. Зачем вам это понадобилось?
0
9 / 6 / 3
Регистрация: 10.01.2020
Сообщений: 330
04.02.2023, 16:42  [ТС]
Цитата Сообщение от Usaga Посмотреть сообщение
Это очень фиговая практика, так делать. Зачем вам это понадобилось?
А выше всех сообщений с кодом недостаточно для этого ответа? )
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
04.02.2023, 17:44
Цитата Сообщение от BeginnerCoderCS Посмотреть сообщение
Класс One это и есть класс внешней программы, я не создаю объект `one`, мне его предоставляет уже готовым программа.
Как выглядит это предоставление?
Кто создает экземпляр класса Two и где этот кто-то берет ссылку на One для его создания?
0
9 / 6 / 3
Регистрация: 10.01.2020
Сообщений: 330
05.02.2023, 00:42  [ТС]
Цитата Сообщение от kolorotur Посмотреть сообщение
Как выглядит это предоставление?
Кто создает экземпляр класса Two и где этот кто-то берет ссылку на One для его создания?
А выше посмотреть сообщение №13?

Представьте что void setup() - одноразовое выполнение при старте, и void loop() бесконечный цикл типа while(true), и несколько объектов в том числе и "one" уже есть в этом окружении.

Поэтому и не хотел это описывать.
Но после вопросов, я надеюсь будут рекомендации. Пусть даже на будущее.

Что так нельзя делать - я понял. Если буду делать, то таких ошибок постараюсь не совершать.

НО сейчас нужно именно в таком окружении работать, и если есть возможности как-то красивее/правильнее из этого выйти, то я весь во внимании

Добавлено через 2 минуты
В переводе на C# NET это

C#
1
2
3
4
5
6
7
8
9
10
11
12
internal class Program
{
    static void Main(string[] args)
    {
        one // здесь уже существует.
        
        while (true)
        {
            // И здесь тоже
        }
    }
}
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16140 / 11264 / 2888
Регистрация: 21.04.2018
Сообщений: 33,109
Записей в блоге: 2
05.02.2023, 01:28
Цитата Сообщение от BeginnerCoderCS Посмотреть сообщение
C#
1
2
3
void loop()
{
    if (ReferenceEquals(one, container["one"].Value))
Если понял правильно, то в container["one"].Value - это текущий сохранённый экземпляр.
А one это переменная в которую поступает новый экземпляр?
Как он поступает? По событию? Или ещё как-то?

Цикл все сделали, насколько понял, для детекции нового экземпляра в переменной one.
Но почему не обновлять two сразу при изменении one?
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
05.02.2023, 01:43
Цитата Сообщение от BeginnerCoderCS Посмотреть сообщение
А выше посмотреть сообщение №13?
Там нет создания экземпляра One.
Плюс вы же сами написали, что это костыль. Зачем нам костыли?
0
9 / 6 / 3
Регистрация: 10.01.2020
Сообщений: 330
05.02.2023, 02:05  [ТС]
Цитата Сообщение от kolorotur Посмотреть сообщение
Там нет создания экземпляра One.
Конечно нет, так как он уже есть в этом окружении. Он создан где-то выше, куда у меня нет доступа.

Цитата Сообщение от Элд Хасп Посмотреть сообщение
Если понял правильно, то в container["one"].Value - это текущий сохранённый экземпляр.
Да

Цитата Сообщение от Элд Хасп Посмотреть сообщение
А one это переменная в которую поступает новый экземпляр?
Который создан не мной, но уже есть. Ни переименовать, ни пересоздать я его не могу.

Цитата Сообщение от Элд Хасп Посмотреть сообщение
Как он поступает? По событию? Или ещё как-то?
Вот просто он уже есть создан в этих двух циклах setup и loop.

Цитата Сообщение от Элд Хасп Посмотреть сообщение
Но почему не обновлять two сразу при изменении one?
Теперь так и сделал. two.UpdateOne(one);

Например как ниже, функции pinMode, digitalWrite, delay уже существуют, как и некоторые объекты такие как `one`.
Они есть всегда, их можно использовать, но инициализировать или пересоздавать нельзя.
https://docs.arduino.cc/built-... sics/Blink

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
05.02.2023, 02:05
Помогаю со студенческими работами здесь

Как передавать значения строкового типа в конструктор через объект класса?
Как передавать значения строкового типа в конструктор через объект класса? Или просто, как передавать знач строкового типа в конструктор? ...

Объект класса, созданный через конструктор копирования, зависим от объекта, с которого брали копию
Объект класса, созданный через конструктор копирования, зависим от объекта, с которого брали копию. При изменении параметров первого...

Почему когда возвращается об'єкт создается новая копия но она создается через конструктор а не через конструктор копии?
Я создал конструктор копий чтоб он визивался при созданию копий функция возвращает обьект но когда возвращает то дальше исполняется код...

Как сделать проверку на действие: добавлять объект или обновлять
Пишу проект на Spring MVC. Есть методы добавить запись @GetMapping(&quot;/add&quot;) public String addGroup(Model model) { ...

Получение значения массива через ссылочный индекс
Dictionary&lt;string, string&gt; sT = new Dictionary&lt;string, string&gt;() { {&quot;test&quot;,&quot;test&quot;}, {&quot;test2&quot;,&quot;test&quot;}, };...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru