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

在Xamarin.Android上,我正在使用Xamarin.Mobile的Xamarin.Geolocation程序包,该程序包具有事件处理程序Geolocator.PositionChanged,可以向其中添加与该签名匹配的方法:void MyMethod( object sender, PositionEventArgs e )。也就是说,给定已声明的Geolocator locator,它将编译为:locator.PositionChanged += MyMethod;

一切正常,直到我重新设计解决方案以使用跨平台的GPSPosition而不是Xamarin PositionEventArgs为止-

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>上给出了编译错误Locator.PositionChanged += MyPositionEventDeleg;

但是我不想传递PositionEventArgs。我想传入一个将PositionEventArgs作为其参数之一的方法。当我将lambda“内联”时,编译器会自动执行所需的转换,因此有可能-我只是不知道正确的方法(声明语法,强制转换还是包装器?)来执行编译器的工作并将其存储在一个变量中。

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

最佳答案

首先,我对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

关于c# - 如何正确地转换或包装事件处理程序的类型? (在+ =中委托(delegate)vs.EventArgs),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39182102/

10-13 01:03