【问题标题】:Cannot convert lambda expression to type 'System.Delegate' because it is not a delegate type? [duplicate]无法将 lambda 表达式转换为类型“System.Delegate”,因为它不是委托类型? [复制]
【发布时间】:2017-09-13 17:46:45
【问题描述】:

我遇到了一个我似乎无法弄清楚的问题,尽管这是 Stackoverflow 上的一个标准问题。

我正在尝试使用以下代码异步更新我的 Bing 地图(请注意,这是来自旧的 Silverlight 项目,似乎不适用于 WPF)

_map.Dispatcher.BeginInvoke(() =>
{
    _map.Children.Clear();
    foreach (var projectedPin in pinsToAdd.Where(pin => PointIsVisibleInMap(pin.ScreenLocation, _map)))
    {
        _map.Children.Add(projectedPin.GetElement(ClusterTemplate));
    }
});

我做错了什么?

【问题讨论】:

  • 那么(Action)(() => ... ) 呢?
  • @acrilige 谢谢!你为什么不把它作为答案????

标签: c# wpf delegates


【解决方案1】:

您必须将其显式转换为 Action 才能转换为 System.Delegate

即:

_map.Dispatcher.BeginInvoke((Action)(() =>
{
    _map.Children.Clear();
    foreach (var projectedPin in pinsToAdd.Where(pin => PointIsVisibleInMap(pin.ScreenLocation, _map)))
    {
        _map.Children.Add(projectedPin.GetElement(ClusterTemplate));
    }
}));

【讨论】:

  • 为了您的兴趣,您可能希望查看我添加到 SLaks 答案中的评论
【解决方案2】:

BeginInvoke() 方法的参数是基类 Delegate

您只能将 lambda 表达式转换为具体的委托类型。

要解决此问题,您需要显式构造一个委托:

BeginInvoke(new MethodInvoker(() => { ... }));

【讨论】:

  • 鲜为人知的事实:在此处使用MethodInvoker 比使用Action / ThreadStart略微更有效——即使签名相同:它在Control.InvokeMarshaledCallbackDo 中有直接支持(通过is/cast)——其他委托类型使用DynamicInvoke。唯一其他直接支持的委托类型是 WaitCallbackEventHandler
【解决方案3】:

试试

Dispatcher.BeginInvoke(new System.Threading.ThreadStart(delegate
{
//Do something
}));

或者使用Action

【讨论】:

  • 为了您的兴趣,您可能希望查看我添加到 SLaks 答案中的评论
  • msdn.microsoft.com/en-us/library/zyzhdc6b.aspx:委托可以是EventHandler的一个实例,这种情况下sender参数会包含这个控件,事件参数会包含EventArgs.Empty。委托也可以是 MethodInvoker 的实例,或任何其他采用 void 参数列表的委托。调用 EventHandler 或 MethodInvoker 委托将比调用另一种委托更快。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多