Подскажите как поменять обьект во всех ссылках
От: Alexander_fx  
Дата: 21.03.16 12:12
Оценка:
Привет
Вопрос может и легкий но ответа не знаю
имеем интерфейс и несколько классов с ссылкой на обьект с таким интерфейсом
один из классов создает новый обьект такого же интерфейса — как поменять все ссылки на теперь уже новый обьект

Interface Iaaa

class A
public obj as Iaaa

class B
public obj as Iaaa

class C
public obj as Iaaa

sub Test

a.obj=new object1
b.obj=a.obj
c.obj=b.obj

Вопрос
например c.obj =new object2
как сделать чтобы a.obj и b.obj теперь ссылались на новый object2 который в c.obj
Re: Подскажите как поменять обьект во всех ссылках
От: Sinix  
Дата: 21.03.16 12:35
Оценка: 150 (7) :))) :)))
Здравствуйте, Alexander_fx, Вы писали:

A_>Вопрос

A_>например c.obj =new object2
A_>как сделать чтобы a.obj и b.obj теперь ссылались на новый object2 который в c.obj

  • Архитектурно — сфероконический: Сделать ValueHolder<T>, всем ссылаться на ValueHolder<T>, менять ValueHolder<T>.Value
  • Fowler-driven: Тут нужен DI с IOC-ом. Не знаю зачем, но нужен.
  • Math-driven: Так это ж легко! Это уже было в симпсонах smalltalk, вам остаётся всего лишь перевести на него ваш код. Не благодарите.
  • Oldschool math-driven:и в фортране тоже.
  • Оппа-оппа pointer-style:
    public static void Replace<T>(T x, T y)
        where T : class
    {
        var size = Marshal.SizeOf(typeof(T));
        var ptr = Marshal.AllocHGlobal(size);
        Marshal.StructureToPtr(y, ptr, false);
        Marshal.PtrToStructure(ptr, x);
        Marshal.FreeHGlobal(ptr);
    }
    (c)
  • Скучный правильный: Заводим класс SomeOpContext с нужными свойствами, протаскиваем контекст, изменяем свойства по необходимости.

    Выбирайте
  • Отредактировано 07.01.2017 16:56 Sinix . Предыдущая версия .
    полезные_советы
    Re[2]: Подскажите как поменять обьект во всех ссылках
    От: Privalov  
    Дата: 22.03.16 12:48
    Оценка: 40 (1)
    Здравствуйте, Sinix, Вы писали:

    S>* Oldschool math-driven:и в фортране тоже.


    Эта штука на Фортране на современных ОС свалится во время выполнения, потому что 5 находится в секции констант, доступной только для чтения.
    В ОС ЕС и/или МС ДОС работает.
    Отредактировано 01.04.2016 2:36 VladD2 . Предыдущая версия .
    Re[3]: Подскажите как поменять обьект во всех ссылках
    От: Sinix  
    Дата: 22.03.16 12:59
    Оценка: :)
    Здравствуйте, Privalov, Вы писали:

    P>Эта штука на Фортране на современных ОС свалится во время выполнения, потому что 5 находится в секции констант, доступной только для чтения.

    P>В ОС ЕС и/или МС ДОС работает.

    Ну, если топикстартер уже перевёл код на фортран, то что ему мешает перейти на MS DOS?
    Re[4]: Подскажите как поменять обьект во всех ссылках
    От: Privalov  
    Дата: 22.03.16 13:04
    Оценка: +1 :)
    Здравствуйте, Sinix, Вы писали:

    S>Ну, если топикстартер уже перевёл код на фортран, то что ему мешает перейти на MS DOS?


    Может нарваться на сегментную организацию памяти, например.
    Re: Подскажите как поменять обьект во всех ссылках
    От: Sinatr Германия  
    Дата: 23.03.16 08:09
    Оценка: -1
    Здравствуйте, Alexander_fx, Вы писали:

    A_>например c.obj =new object2

    A_>как сделать чтобы a.obj и b.obj теперь ссылались на новый object2 который в c.obj

    Используя property и static хранилище:

    static class ObjManager
    {
        public static IAaa Ojb;
    }
    
    class A
    {
        public IAaa Obj
        {
            get { return ObjManager.Ojb; }
            set { ObjManager.Ojb = value; }
        }
    }
    
    class B
    {
        public IAaa Obj
        {
            get { return ObjManager.Ojb; }
            set { ObjManager.Ojb = value; }
        }
    }

    Возможны вариации (Dictionary вместо static , синглтон вместо static, инжектирование через конструктор или еще как, и тд.). Можно использовать базовый клас, чтобы не повторять функционал property во всех классах (хранилищем может быть static field базового класса).
    ---
    ПроГLамеры объединяйтесь..
    Отредактировано 23.03.2016 8:11 Sinatr . Предыдущая версия .
    Re[2]: Подскажите как поменять обьект во всех ссылках
    От: Sinix  
    Дата: 23.03.16 08:19
    Оценка:
    Здравствуйте, Sinatr, Вы писали:

    S>Используя property и static хранилище:

    От тёмной стороны совет этот исходит. Проблем принесёт больше, чем решает.
    Re[3]: Подскажите как поменять обьект во всех ссылках
    От: Sinatr Германия  
    Дата: 23.03.16 09:17
    Оценка:
    Здравствуйте, Sinix, Вы писали:

    S>От тёмной стороны совет этот исходит. Проблем принесёт больше, чем решает.

    Сфероконических проблем? А поконкретнее? Сам не пользовался, это решение первое что пришло в голову. Проблемы с сериализацией? "Собирателем мусора"?
    ---
    ПроГLамеры объединяйтесь..
    Re[4]: Подскажите как поменять обьект во всех ссылках
    От: Sinix  
    Дата: 23.03.16 09:45
    Оценка:
    Здравствуйте, Sinatr, Вы писали:


    S>Сфероконических проблем? А поконкретнее? Сам не пользовался, это решение первое что пришло в голову. Проблемы с сериализацией? "Собирателем мусора"?


    С GC — да, если использовать ConditionalWeakTable.
    Если не использовать — велкам в утечки памяти.

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

    Лучше такие штуки передавать через экземпляр класса, который протаскивается по всей цепочке вызовов. Если лень протаскивать вручную, то есть волшебный AsyncLocal<T>, его наконец сделали правильно, в отличие от ThreadLocal/CallContext.LogicalGet-SetData()/CorrelationManager.
    Re[5]: Подскажите как поменять обьект во всех ссылках
    От: Sinatr Германия  
    Дата: 23.03.16 12:34
    Оценка:
    Здравствуйте, Sinix, Вы писали:

    S>Если не использовать — велкам в утечки памяти.


    Попытался представить сценарий появления ошибки — не смог. Можете поконкретнее? Кстате, похожий механизм "обвертки свойствами" я использую в MVVM WPF приложениях, когда ViewModel свойство всего-лишь редиректит к модельке, причем моделька иногда синглтон или вообще статический класс. Потому мне интересно что не так. Для утечки память где-то должна хранится ссылка на обьект, который больше никем не используется, не пойму где тут та самая ссылка?

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


    Не понятно. Чем отличается передача экземляра хранилища или оболочки от наличия и использования прямой ссылки на некий класс (в данном случае статический, но я бы сделал базовый класс)? Юнит-тесты что-ли опять? Я лично их не использую, в условиях задачи этого тоже нет.

    В чем выражается "непредсказуемость"? Имеется в виду отсутствие механизма извещения об изменении, и как следствие, неопределенностью актуальности значения? Опять же, в постановке задачи не было такого, но никто не мешает добавить событие, синхронизацию (если хочется многозадачности) и т.д.

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

    S>Лучше такие штуки передавать через экземпляр класса, который протаскивается по всей цепочке вызовов. Если лень протаскивать вручную, то есть волшебный AsyncLocal<T>, его наконец сделали правильно, в отличие от ThreadLocal/CallContext.LogicalGet-SetData()/CorrelationManager.


    Вы видите проблему шире чем я. Мне неочевидна связь моего решения с какими-то проблемами потоков (с которыми я еще к тому же и не сталкивался ни разу, впервые слышу о перечисленных понятиях, ThreadStatic слышал, но ни разу не использовал).

    Преимущество использования экземпляра очевидны, но опять же зависит от требований. "Протаскивание" чего-то может быть бесполезной операцией, если эти преимущества наличия экземпляра не собираются использовать ( принцип YAGNI).
    ---
    ПроГLамеры объединяйтесь..
    Re[6]: Подскажите как поменять обьект во всех ссылках
    От: Sinix  
    Дата: 23.03.16 12:56
    Оценка: 4 (1)
    Здравствуйте, Sinatr, Вы писали:

    Disclaimer: я как всегда отвечаю про общий случай, вы про ваш конкретный
    Конкретно у вас всё ок. По крайней мере пока не будет больше одного view. Ниже ответы для общего случая:


    S>>Если не использовать — велкам в утечки памяти.

    S>Попытался представить сценарий появления ошибки — не смог.
    Ну вот навскидку:
    SomeClass.SetStaticProperty(someUniqueKey, refToHeavyObject);
    // потоку приходит ThreadAbortException

    собственно, всё
    Если без словарика, то у вас async-методы будут периодически устраивать гонки за значением.


    S> Можете поконкретнее? Кстате, похожий механизм "обвертки свойствами" я использую в MVVM WPF приложениях, когда ViewModel свойство всего-лишь редиректит к модельке, причем моделька иногда синглтон или вообще статический класс. Потому мне интересно что не так. Для утечки память где-то должна хранится ссылка на обьект, который больше никем не используется, не пойму где тут та самая ссылка?

    Не, если мы говорим про ситуацию "владеем всем кодом" — всё ок.
    А вот если ваш view понадобится несколько раз отобразить, то надо как-то сопоставлять view<>моделька. И тогда см предыдущий пункт


    S>>На самом деле проблема в другом: вы сознательно добавляете в метод зависимость от сторонних эффектов.

    S>Не понятно. Чем отличается передача экземляра хранилища или оболочки от наличия и использования прямой ссылки на некий класс?
    Тем, что static-поле может _незаметно_ для вас использоваться другими потоками/частями кода.
    В случае протаскивания контекста контроль целиком и полностью на вас. Никуда не отдали — никто доступа не получил.
    Это не везде важно, понятное дело.


    S>синхронизацию (если хочется многозадачности) и т.д.

    Ну это по умолчанию уже должно быть. В современном шарпе весь код должен быть заточен на "одновременно может быть вызвано несколько кусков кода". Главным образом из-за async.
    Re[7]: Подскажите как поменять обьект во всех ссылках
    От: Sinatr Германия  
    Дата: 23.03.16 13:40
    Оценка:
    Здравствуйте, Sinix, Вы писали:

    S> async-методы будут периодически устраивать гонки за значением

    S> В современном шарпе весь код должен быть заточен на "одновременно может быть вызвано несколько кусков кода". Главным образом из-за async.

    Ну я так и подумал, что видимо имеется в виду какой-то сценарий. Спасибо за обьяснения. С я async не дружу особо, потому и опыта указанных проблем нет. Больше добавить как-бы нечего.
    ---
    ПроГLамеры объединяйтесь..
     
    Подождите ...
    Wait...
    Пока на собственное сообщение не было ответов, его можно удалить.