如何反编译.Net 事件?

How to decompile .Net events?

Xamarin Assebly Browser 为事件生成以下代码

public event BooleanPreference.ValueChangedHandler ValueChanged {
    [MethodImpl (MethodImplOptions.Synchronized)]
    add {
        this.ValueChanged = (BooleanPreference.ValueChangedHandler)Delegate.Combine (this.ValueChanged, value);
    }
    [MethodImpl (MethodImplOptions.Synchronized)]
    remove {
        this.ValueChanged = (BooleanPreference.ValueChangedHandler)Delegate.Remove (this.ValueChanged, value);
    }
}

编译它会产生错误,例如

Error CS0079: The event `EdB.Interface.BooleanPreference.ValueChanged' can only appear on the left hand side of `+=' or `-=' operator (CS0079) (EdB.Interface)

如何转换代码以使其工作?

稍后在代码中引用事件

if ((!flag.HasValue || flag.Value != this.boolValue) && this.ValueChanged != null) {
    this.ValueChanged (value);
}

导致同样的错误

Error CS0079: The event `EdB.Interface.BooleanPreference.ValueChanged' can only appear on the left hand side of `+=' or `-=' operator (CS0079) (EdB.Interface)

编辑:

以下代码

public delegate void ValueChangedHandler (bool value);

public event BooleanPreference.ValueChangedHandler ValueChanged;

protected void OnValueChanged(EventArgs e) {
    var evt = ValueChanged;
    if (evt != null) {
        evt(this, e);
    }
}

生产

Error CS1593: Delegate `EdB.Interface.BooleanPreference.ValueChangedHandler' does not take `2' arguments (CS1593) (EdB.Interface)

C# 中的基本事件声明,如下所示:

public event EventHandler EventName;

最终给你一个标识符,EventName,它有两个含义,因为编译器使用这个声明来创建两个东西:

  1. 一个字段,保存事件的委托
  2. 一个事件,声明添加和删除访问器来操作这个字段

但是,您仍然只有一个标识符,EventName,但其确切含义取决于其上下文:

  1. 对字段的引用,只要您在声明事件的 class 中
  2. 对事件的引用,只要您在声明事件的class之外

现实中,创建了这样的代码:

private EventHandler _EventName;

public event EventHandler EventName
{
    add
    {
        _EventName = (EventHandler)Delegate.Combine(_EventName, value);
    }
    remove
    {
        _EventName = (EventHandler)Delegate.Remove(_EventName, value);
    }
}

但是,由于您使用了基本语法来声明事件,因此编译器将默默地修复所有引用以引用字段(在 class 内)或事件(在 class 之外) ).

这是您要编写的 OnEventName 方法的示例:

protected void OnEventName(...)
{
    var evt = EventName;
    if (evt != null)
        evt(this, ...);
}

编译器会默默地重写为:

protected void OnEventName(...)
{
    var evt = _EventName; // reference to the field
    if (evt != null)
        evt(this, ...);
}

显然 Xamarin 反编译器不理解这种双重含义。基本上你将不得不根据上面的例子重写代码。