如何反编译.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
,它有两个含义,因为编译器使用这个声明来创建两个东西:
- 一个字段,保存事件的委托
- 一个事件,声明添加和删除访问器来操作这个字段
但是,您仍然只有一个标识符,EventName
,但其确切含义取决于其上下文:
- 对字段的引用,只要您在声明事件的 class 中
- 对事件的引用,只要您在声明事件的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 反编译器不理解这种双重含义。基本上你将不得不根据上面的例子重写代码。
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
,它有两个含义,因为编译器使用这个声明来创建两个东西:
- 一个字段,保存事件的委托
- 一个事件,声明添加和删除访问器来操作这个字段
但是,您仍然只有一个标识符,EventName
,但其确切含义取决于其上下文:
- 对字段的引用,只要您在声明事件的 class 中
- 对事件的引用,只要您在声明事件的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 反编译器不理解这种双重含义。基本上你将不得不根据上面的例子重写代码。