Я не уверен, почему вы сосредотачиваетесь на «наблюдаемых», но C# уже имеет систему для взаимодействия типа подписчик / издатель, а именно события .
Вы можете использовать шаблон прокси в сочетании с наследованием для достижения желаемого:
class FooEventProxy : Foo
{
public event EventHandler BarCall;
/*
* Retype all constructors of Foo here and delegate them to base.
*/
public override void Bar()
{
OnBarCall(new EventHandler());
base.Bar();
}
protected virtual void OnBarCall(EventHandler e)
{
EventHandler event = BarCall;
if (event != null)
{
event(this, e);
}
}
}
Предполагается, что вы управляете созданием Foo
и можете просто заставить все созданные им места использовать вместо FooEventProxy
.
Если вы не можете, тогда вы только что выяснили причину, по которой все ваши логики создания c хранятся на фабриках, и ситуация немного сложнее. Если вы можете получить доступ ко всем аргументам Foo
, с которыми он был создан, вы, вероятно, можете просто скопировать их в новый экземпляр FooEventProxy
. Если вы не можете, то мы находимся в загадке: вы хотите заменить аргумент типа Foo
на FooEventProxy
, но вы не можете гарантировать, что внутреннее состояние аргумента будет правильно передано в новый экземпляр. . Вы не можете просто направить вызовы виртуальных методов в обернутый экземпляр, поскольку невиртуальные методы все еще могут быть вызваны и не будут работать правильно - нарушение принципа Лискова. Таким образом, вам нужно либо скопировать внутреннее состояние Foo
точно в FooEventProxy
, используя массивное отражение вуду, либо, ну, вам не повезло, и вы только что выяснили причину зависимости от интерфейсов / абстрактов, а не конкретных классы.
Я не знаю, как скопировать все данные базового класса из существующего экземпляра в новый экземпляр производного типа, что было у меня в голове, поэтому, если вы действительно думаете, что это то, что вы хотите, задайте еще один вопрос специально для этого.