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)
答案 0 :(得分:2)
C#中的基本事件声明,如下所示:
public event EventHandler EventName;
最终会给你一个标识符EventName
,它有两个含义,因为编译器使用单个声明来创建两个东西:
但是,您仍然只有一个标识符EventName
,但其确切含义取决于其上下文:
实际上,创建了这种代码:
private EventHandler _EventName;
public event EventHandler EventName
{
add
{
_EventName = (EventHandler)Delegate.Combine(_EventName, value);
}
remove
{
_EventName = (EventHandler)Delegate.Remove(_EventName, value);
}
}
但是,由于您使用基本语法来声明事件,编译器将默默地修复所有引用,以引用字段(在类内)或事件(在类外)。
这是您要编写的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反编译器并不了解这种双重含义。基本上你必须根据上面的例子重写代码。