代码之家  ›  专栏  ›  技术社区  ›  SimonAx

无需装箱即可将对象转换为类型

  •  0
  • SimonAx  · 技术社区  · 8 年前

    我正在尝试扩展事件聚合器,类似于中描述的事件聚合器 blog post on Event Aggregator 用Rx。使用博客帖子中的代码,我可以通过创建订阅来收听事件:

    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 对象这可以在VisualStudio的Watch窗口的屏幕截图中看到。

    enter image description here

    是否有任何方法可以动态强制转换对象,使结果不被装箱?

    使现代化 除了这段代码中的内容之外,我还尝试了(1)使用自定义类型转换器用TypeConverter属性修饰Foo,以及(2)反射+泛型。在所有情况下,结果都是典型的 object 而不是 .

    0 回复  |  直到 8 年前