Привет
Вопрос может и легкий но ответа не знаю
имеем интерфейс и несколько классов с ссылкой на обьект с таким интерфейсом
один из классов создает новый обьект такого же интерфейса — как поменять все ссылки на теперь уже новый обьект
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: Подскажите как поменять обьект во всех ссылках
Здравствуйте, 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 с нужными свойствами, протаскиваем контекст, изменяем свойства по необходимости.
Здравствуйте, Sinix, Вы писали:
S>* Oldschool math-driven: …и в фортране тоже.
Эта штука на Фортране на современных ОС свалится во время выполнения, потому что 5 находится в секции констант, доступной только для чтения.
В ОС ЕС и/или МС ДОС работает.
Здравствуйте, Privalov, Вы писали:
P>Эта штука на Фортране на современных ОС свалится во время выполнения, потому что 5 находится в секции констант, доступной только для чтения. P>В ОС ЕС и/или МС ДОС работает.
Ну, если топикстартер уже перевёл код на фортран, то что ему мешает перейти на MS DOS?
Re[4]: Подскажите как поменять обьект во всех ссылках
Здравствуйте, 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 базового класса).
Здравствуйте, Sinix, Вы писали:
S>От тёмной стороны совет этот исходит. Проблем принесёт больше, чем решает.
Сфероконических проблем? А поконкретнее? Сам не пользовался, это решение первое что пришло в голову. Проблемы с сериализацией? "Собирателем мусора"?
---
ПроГLамеры объединяйтесь..
Re[4]: Подскажите как поменять обьект во всех ссылках
На самом деле проблема в другом: вы сознательно добавляете в метод зависимость от сторонних эффектов. Ну, т.е. изменяя значение свойства из одного куска кода, вы непредсказуемым образом меняете поведение другого.
Лучше такие штуки передавать через экземпляр класса, который протаскивается по всей цепочке вызовов. Если лень протаскивать вручную, то есть волшебный AsyncLocal<T>, его наконец сделали правильно, в отличие от ThreadLocal/CallContext.LogicalGet-SetData()/CorrelationManager.
Re[5]: Подскажите как поменять обьект во всех ссылках
Здравствуйте, Sinix, Вы писали:
S>Если не использовать — велкам в утечки памяти.
Попытался представить сценарий появления ошибки — не смог. Можете поконкретнее? Кстате, похожий механизм "обвертки свойствами" я использую в MVVM WPF приложениях, когда ViewModel свойство всего-лишь редиректит к модельке, причем моделька иногда синглтон или вообще статический класс. Потому мне интересно что не так. Для утечки память где-то должна хранится ссылка на обьект, который больше никем не используется, не пойму где тут та самая ссылка?
S>На самом деле проблема в другом: вы сознательно добавляете в метод зависимость от сторонних эффектов. Ну, т.е. изменяя значение свойства из одного куска кода, вы непредсказуемым образом меняете поведение другого.
Не понятно. Чем отличается передача экземляра хранилища или оболочки от наличия и использования прямой ссылки на некий класс (в данном случае статический, но я бы сделал базовый класс)? Юнит-тесты что-ли опять? Я лично их не использую, в условиях задачи этого тоже нет.
В чем выражается "непредсказуемость"? Имеется в виду отсутствие механизма извещения об изменении, и как следствие, неопределенностью актуальности значения? Опять же, в постановке задачи не было такого, но никто не мешает добавить событие, синхронизацию (если хочется многозадачности) и т.д.
Требуется изменить значение а.Obj после изменения b.Obj, все что необходимо это обеспечить их согласованность, в данном случае это обеспечивается за счет того, что оба ссылаются на один обьект.
S>Лучше такие штуки передавать через экземпляр класса, который протаскивается по всей цепочке вызовов. Если лень протаскивать вручную, то есть волшебный AsyncLocal<T>, его наконец сделали правильно, в отличие от ThreadLocal/CallContext.LogicalGet-SetData()/CorrelationManager.
Вы видите проблему шире чем я. Мне неочевидна связь моего решения с какими-то проблемами потоков (с которыми я еще к тому же и не сталкивался ни разу, впервые слышу о перечисленных понятиях, ThreadStatic слышал, но ни разу не использовал).
Преимущество использования экземпляра очевидны, но опять же зависит от требований. "Протаскивание" чего-то может быть бесполезной операцией, если эти преимущества наличия экземпляра не собираются использовать ( принцип YAGNI).
---
ПроГLамеры объединяйтесь..
Re[6]: Подскажите как поменять обьект во всех ссылках
Disclaimer: я как всегда отвечаю про общий случай, вы про ваш конкретный
Конкретно у вас всё ок. По крайней мере пока не будет больше одного view. Ниже ответы для общего случая:
S>>Если не использовать — велкам в утечки памяти. S>Попытался представить сценарий появления ошибки — не смог.
Ну вот навскидку:
SomeClass.SetStaticProperty(someUniqueKey, refToHeavyObject);
// потоку приходит ThreadAbortException
собственно, всё
Если без словарика, то у вас async-методы будут периодически устраивать гонки за значением.
S> Можете поконкретнее? Кстате, похожий механизм "обвертки свойствами" я использую в MVVM WPF приложениях, когда ViewModel свойство всего-лишь редиректит к модельке, причем моделька иногда синглтон или вообще статический класс. Потому мне интересно что не так. Для утечки память где-то должна хранится ссылка на обьект, который больше никем не используется, не пойму где тут та самая ссылка?
Не, если мы говорим про ситуацию "владеем всем кодом" — всё ок.
А вот если ваш view понадобится несколько раз отобразить, то надо как-то сопоставлять view<>моделька. И тогда см предыдущий пункт
S>>На самом деле проблема в другом: вы сознательно добавляете в метод зависимость от сторонних эффектов. S>Не понятно. Чем отличается передача экземляра хранилища или оболочки от наличия и использования прямой ссылки на некий класс?
Тем, что static-поле может _незаметно_ для вас использоваться другими потоками/частями кода.
В случае протаскивания контекста контроль целиком и полностью на вас. Никуда не отдали — никто доступа не получил.
Это не везде важно, понятное дело.
S>синхронизацию (если хочется многозадачности) и т.д.
Ну это по умолчанию уже должно быть. В современном шарпе весь код должен быть заточен на "одновременно может быть вызвано несколько кусков кода". Главным образом из-за async.
Re[7]: Подскажите как поменять обьект во всех ссылках
Здравствуйте, Sinix, Вы писали:
S> async-методы будут периодически устраивать гонки за значением S> В современном шарпе весь код должен быть заточен на "одновременно может быть вызвано несколько кусков кода". Главным образом из-за async.
Ну я так и подумал, что видимо имеется в виду какой-то сценарий. Спасибо за обьяснения. С я async не дружу особо, потому и опыта указанных проблем нет. Больше добавить как-бы нечего.