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

如何强制WebSocketClient类实例在实例化时遵循IWebSocketClient接口约束

核心原因

C#的接口约束是编译时类型检查,仅对声明为接口类型的变量生效。你用var接收new WebSocketClient(uri)的返回值时,编译器会直接推断变量类型为WebSocketClient实现类,自然可以访问实现类的所有公开成员,不受IWebSocketClient接口的限制。

可行解决方案

方案1:私有构造+工厂方法返回接口(最推荐,完全杜绝直接实例化实现类)

把WebSocketClient的构造函数设为私有,仅暴露静态工厂方法,返回值强制声明为IWebSocketClient:

public class WebSocketClient : IWebSocketClient
{
    // 构造函数私有,外部无法直接new实例
    private WebSocketClient(Uri uri)
    {
    }

    // 对外暴露的静态工厂方法,固定返回接口类型
    public static IWebSocketClient Create(Uri uri)
    {
        return new WebSocketClient(uri);
    }

    /// <inheritdoc />
    public WebSocketState State => _webSocket.State;

    public async Task ConnectAsync(CancellationToken cancellationToken)
    {
        // 实现逻辑
    }
}

使用时即使写var,编译器推断的类型也是IWebSocketClient,无法调用ConnectAsync,完全符合预期:

// 自动推断类型为IWebSocketClient
var webSocketClient = WebSocketClient.Create(uri);
// 下面的调用会直接编译报错,提示找不到ConnectAsync方法
await webSocketClient.ConnectAsync(CancellationToken.None).ConfigureAwait(false);

方案2:内部类+仅暴露接口(适合类库开发场景)

如果WebSocketClient是类库内部实现,不需要对外暴露,可以把WebSocketClient设为internal,仅对外暴露IWebSocketClient接口和工厂方法:

// 实现类设为internal,仅当前程序集可访问,外部程序集看不到该类型
internal class WebSocketClient : IWebSocketClient
{
    public WebSocketClient(Uri uri)
    {
    }
    // 其余实现省略
}

// 对外公开的工厂类
public static class WebSocketFactory
{
    public static IWebSocketClient CreateClient(Uri uri)
    {
        return new WebSocketClient(uri);
    }
}

外部程序集根本无法感知WebSocketClient类型的存在,自然不可能用var推断为实现类,只能用接口类型接收实例。

方案3:调整非接口成员的访问级别

如果ConnectAsync本身就不需要对外暴露,直接把它的访问修饰符改为private或internal即可,这样不管变量是什么类型,外部都无法调用该方法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 19:45:01