如何正确地转换或包装事件处理程序的类型? (委托与_ =中的EventArgs)

时间:2016-08-27 14:14:52

标签: c# events declaration

我有一个跨平台class GPSPosition,其中包含我们需要的GPS单元字段。

在Xamarin.Android上我使用的是Xamarin.Mobile的Xamarin.Geolocation包,它有一个事件处理程序Geolocator.PositionChanged,可以添加与此签名匹配的方法:void MyMethod( object sender, PositionEventArgs e )。也就是说,给定声明的Geolocator locator,这将编译:{{1​​}}。

这很好用,直到我重新使用我的解决方案来使用我们的跨平台locator.PositionChanged += MyMethod;,而不是Xamarin GPSPosition - 这是:

PositionEventArgs

To"转换"使用public class PositionEventArgs : EventArgs { public Position Position { get; set; } ... } Position,这有效:

GPSPosition

但现在我想存储该事件处理程序?代表?在局部变量中,所以我可以在以后删除它:

public delegate void GPSPositionDeleg( GPSPosition position );

// Convert Position to GPSPosition.
GPSPosition ToGPSPosition( Position pos ) {
    ....
}

public void Start( GPSPositionDeleg positionDeleg )
{
    Locator.PositionChanged += ( sender, e ) =>
        positionDeleg( ToGPSPosition( e.Position ) );
}

这会在delegate void PositionEventDeleg( object sender, PositionEventArgs e ); PositionEventDeleg MyPositionEventDeleg; public void Start( GPSPositionDeleg positionDeleg ) { MyPositionEventDeleg = ( sender, e ) => positionDeleg( ToGPSPosition( e.Position ) ); Locator.PositionChanged += MyPositionEventDeleg; } 行上产生编译错误Error CS0029: Cannot implicitly convert type LiveCaddie.GPSEngine.PositionEventDeleg to System.EventHandler<Xamarin.Geolocation.PositionEventArgs>

但我不想传递PositionEventArgs。我想传递一个方法,将PositionEventArgs作为其参数之一。当我把lambda&#34; inline&#34;时,编译器自动完成了所需的转换,所以有可能 - 我只是不知道正确的(声明语法,强制转换或包装?)来做什么编译器,并将其存储在变量中。

Locator.PositionChanged += MyPositionEventDeleg;的正确定义是什么?也就是说,我可以保存lambda以传递给PositionEventDeleg的类型,以便以后在PositionChanged += ...中使用

1 个答案:

答案 0 :(得分:0)

首先,我对EventHandler的含义感到困惑。我认为字段PositionChanged是EventHandler,但似乎添加到它的方法是EventHandlers。

正确的定义,而不是之前的PositionEventDeleg MyPositionEventDeleg;,是:

EventHandler<PositionEventArgs> MyPositionEventHandler;

然后可以将lambda存储到:

MyPositionEventHandler = ( sender, e ) => positionDeleg( ToGPSPosition( e.Position ) );
Locator.PositionChanged += MyPositionEventHandler;

正如我所指出的,现在其他人可以做到:

Locator.PositionChanged -= MyPositionEventHandler;

或者更严格:

if (MyPositionEventHandler != null) {
    Locator.PositionChanged -= MyPositionEventHandler;
    MyPositionEventHandler = null;
}

如果从未设置MyPositionEventHandler,则要避免出现空例外,并明确表示MyPositionEventHandler已被删除。