【问题标题】:Unsubscribe another class from an event with Reflection使用反射从事件中取消订阅另一个类
【发布时间】:2015-05-24 04:20:30
【问题描述】:

我正在使用一个非常封闭但不满足我需要的第三方库(Xamarin.Forms、平移/缩放手势)。

我破解了一个变通办法,但随着他们的最新更新 (1.4) 变通办法停止工作。查看他们的代码,如果我可以取消订阅库的一个类以监听事件,我可以修复我的解决方法,问题是该类涉及了几个应该受到保护的私有方法。

这是我的代码:

    public class InteractiveEventTracker: EventTracker{
        public InteractiveEventTracker(IVisualElementRenderer renderer)
            : base(renderer)
        {
            this.Renderer = renderer; 
            var elChgMethod = typeof(EventTracker).GetMethod("OnElementChanged", BindingFlags.NonPublic | BindingFlags.Instance);
            var elChgDelegate = Delegate.CreateDelegate(typeof(EventHandler<VisualElementChangedEventArgs>), elChgMethod);
// Compile-time errors, how do I spell that?
            renderer.ElementChanged -= new EventHandler<VisualElementChangedEventArgs>(elChgDelegate); 
        }

编译时错误是 表达式表示需要“类型”或“方法组”的“变量”。

我的 InteractiveEventTracker 必须调用如下所示的基本构造函数:

public EventTracker(IVisualElementRenderer renderer)
    {
        if (renderer == null)
        {
            throw new ArgumentNullException("renderer");
        }
        this.renderer = renderer;
        this.renderer.ElementChanged += new EventHandler<VisualElementChangedEventArgs>(this.OnElementChanged); // this is what I want to unsubscribe
    }
    private void OnElementChanged(object sender, VisualElementChangedEventArgs e){
...
    }

我如何取消订阅基类 EventTracker 来监听事件?

【问题讨论】:

  • 那么为什么不this.renderer.ElementChanged -= new EventHandler&lt;VisualElementChangedEventArgs&gt;(this.OnElementChanged);?你可以把private改成protected试试看
  • 这是一个第三方库,我无法更改 EventTracker 本身
  • 在哪一行出错?当你取消订阅?还是创建委托?
  • 在我尝试取消订阅的那一行出现编译时错误

标签: .net reflection xamarin.forms


【解决方案1】:

您的代码中有一些错误:

1) 错误创建委托

Delegate.CreateDelegate(typeof(EventHandler<VisualElementChangedEventArgs>), elChgMethod);

这个重载方法

创建指定类型的委托来表示指定的静态方法。

所以你还需要传递实例,比如

Delegate.CreateDelegate(typeof(EventHandler<VisualElementChangedEventArgs>), this, elChgMethod);

2) 您需要将创建的委托显式转换为您的 EventHandler 类型,例如

renderer.ElementChanged -= (EventHandler<VisualElementChangedEventArgs>)elChgDelegate;

所以你需要像这样改变你的代码

var elChgMethod = typeof(EventTracker).GetMethod("OnElementChanged", BindingFlags.NonPublic | BindingFlags.Instance);
var elChgDelegate = Delegate.CreateDelegate(typeof(EventHandler<VisualElementChangedEventArgs>), this, elChgMethod);
renderer.ElementChanged -= (EventHandler<VisualElementChangedEventArgs>)elChgDelegate;

【讨论】:

    猜你喜欢
    • 2021-04-03
    • 1970-01-01
    • 2020-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多