我正在尝试使用Rx扩展类似于blog post on Event Aggregator中描述的事件聚合器。使用博客文章中的代码,我可以通过创建订阅来收听事件:
int value = 0;
_eventAggregator.GetEvent<Foo>().Subscribe(x => value = x.Value)
其中
class Foo : IConvertible
{
public int Value {get;set;}
//Several IConvertible omitted
public object ToType(Type conversionType, IFormatProvider provider)
{
return new FooEvent();
}
}
发布新活动也很简单:
_eventAggregator.Publish(new Foo {Value = 1});
现在,我需要将两个或更多事件包装到一个复合中,并以顺序方式发布这些数据。我的尝试就在这里:
public void Publish<TEventArgs>(TEventArgs eventData)
{
var composite = eventData as IComposite;
if (composite == null)
{
_eventAggregator.Publish(eventData);
return;
}
var convertedType = Convert.ChangeType(composite.OnNext, composite.OnNextType); //dynamic cast
var castedType = (Foo)composite.OnNext; //static cast
_eventAggregator.Publish(convertedType); //never received
_eventAggregator.Publish(castedType); //is received
}
其中
public interface IComposite
{
Type OnNextType { get; }
object OnNext { get; }
}
问题是事件订阅是静态的并且在编译时是已知的,但是数据的发布是在运行时并且类型不是静态知道的。
在代码段中,我尝试使用Convert.ChangeType
,但生成的对象是一个包装/装箱Foo
对象。这可以在Visual Studio的Watch窗口的屏幕截图中看到。
是否有任何动态转换对象的方法,以便结果不会被装箱?
更新除了此代码段中的内容之外,我还尝试过(1)使用TypeConverter属性使用自定义TypeConverter和(2)反射+泛型来装饰Foo。在所有情况下,结果都是object
类型,而不是Foo
。