You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

转换Lambda表达式触发CS1660错误?PowerShell扩展Websocket.Client遇阻

问题场景

需要优化PowerShell脚本实现多源信息收集的事件驱动处理,其中WebSocket数据源选用Websocket.Client模块,该模块原生不支持触发.NET事件,因此尝试继承WebsocketClient类扩展自定义事件,但编译时出现CS1660错误。

自定义扩展类代码

if (-not ("WebsocketClientExt" -as [type])) {
  $cp = @"
using System;
using System.Net;
using System.Net.WebSockets;
using Websocket.Client;
using Websocket.Client.Models;

public class WebsocketClientExt : WebsocketClient {
  
  public event EventHandler<DisconnectionInfo> Disconnection;
  
  public WebsocketClientExt( Uri url ): base(url) { }
  
  public void SubscribeEvents () {
    DisconnectionHappened.Subscribe(info => Disconnection?.Invoke(this, info));
  }
    
}
"@
  Add-Type -TypeDefinition $cp -ReferencedAssemblies @( 'Websocket.Client', 'System.Net.WebSockets', 'System.Net.WebSockets.Client' )
}

编译错误信息

Add-Type:
Line |
  22 |      Add-Type -TypeDefinition $cp -ReferencedAssemblies @( 'Websocket. …
     |      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | (15,41): error CS1660: Impossible de convertir expression lambda en type 'IObserver<DisconnectionInfo>', car il ne s'agit pas d'un type délégué
        DisconnectionHappened.Subscribe(info => Disconnection?.Invoke(this, info));

英文释义:无法将Lambda表达式转换为“IObserver”类型,因为它不是委托类型。

错误原因

DisconnectionHappened是IObservable<DisconnectionInfo>类型,其原生Subscribe方法要求传入实现IObserver<DisconnectionInfo>接口的对象,而非直接传入Lambda表达式。你提到的EventHandler是委托类型,但这里的问题在于IObservable的订阅机制依赖Reactive Extensions(Rx)的扩展方法才能支持Lambda参数,当前代码未引用对应的Rx程序集。

解决方案

方案1:添加Rx程序集引用并使用扩展方法

修改Add-Type的引用列表,加入System.Reactive.Linq,即可使用支持Lambda的Subscribe扩展方法:

if (-not ("WebsocketClientExt" -as [type])) {
  $cp = @"
using System;
using System.Net;
using System.Net.WebSockets;
using Websocket.Client;
using Websocket.Client.Models;

public class WebsocketClientExt : WebsocketClient {
  
  public event EventHandler<DisconnectionInfo> Disconnection;
  
  public WebsocketClientExt( Uri url ): base(url) { }
  
  public void SubscribeEvents () {
    DisconnectionHappened.Subscribe(info => Disconnection?.Invoke(this, info));
  }
    
}
"@
  # 添加System.Reactive.Linq引用
  Add-Type -TypeDefinition $cp -ReferencedAssemblies @( 'Websocket.Client', 'System.Net.WebSockets', 'System.Net.WebSockets.Client', 'System.Reactive.Linq' )
}

方案2:手动实现IObserver接口

如果不想依赖Rx扩展,可以自定义实现IObserver<DisconnectionInfo>来处理断开事件:

if (-not ("WebsocketClientExt" -as [type])) {
  $cp = @"
using System;
using System.Net;
using System.Net.WebSockets;
using Websocket.Client;
using Websocket.Client.Models;

public class WebsocketClientExt : WebsocketClient {
  
  public event EventHandler<DisconnectionInfo> Disconnection;
  
  private DisconnectionObserver _disconnectionObserver;

  public WebsocketClientExt( Uri url ): base(url) {
    _disconnectionObserver = new DisconnectionObserver(this);
  }
  
  public void SubscribeEvents () {
    DisconnectionHappened.Subscribe(_disconnectionObserver);
  }

  private class DisconnectionObserver : IObserver<DisconnectionInfo> {
    private readonly WebsocketClientExt _parent;

    public DisconnectionObserver(WebsocketClientExt parent) {
      _parent = parent;
    }

    public void OnCompleted() { }

    public void OnError(Exception error) { }

    public void OnNext(DisconnectionInfo value) {
      _parent.Disconnection?.Invoke(_parent, value);
    }
  }
}
"@
  Add-Type -TypeDefinition $cp -ReferencedAssemblies @( 'Websocket.Client', 'System.Net.WebSockets', 'System.Net.WebSockets.Client' )
}

补充说明

两种方案中,方案1更简洁——Websocket.Client本身依赖Reactive Extensions,添加引用不会引入额外依赖;方案2则完全不依赖Rx扩展方法,适合需要最小化依赖的场景。

内容的提问来源于stack exchange,提问作者Alain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 22:58:16