【发布时间】:2022-01-12 02:57:03
【问题描述】:
如何强制WebSocketClient 的类实例在其实例化中使用IWebSocketClient 接口?
例如。我没有在界面中列出ConnectAsync 方法,我希望代码不允许我调用它。
IWebSocketClient webSocketClient = new WebSocketClient(uri);
await webSocketClient
.ConnectAsync(CancellationToken.None) // ConnectAsync is missing which is expected behavior
.ConfigureAwait(false);
var webSocketClient = new WebSocketClient(uri);
await webSocketClient
.ConnectAsync(CancellationToken.None) // it allows me to call it, which is not expected behavior
.ConfigureAwait(false);
片段
public interface IWebSocketClient : IDisposable
{
WebSocketState State { get; }
}
public class WebSocketClient : IWebSocketClient
{
public WebSocketClient(Uri uri)
{
}
/// <inheritdoc />
public WebSocketState State => _webSocket.State;
public async Task ConnectAsync(CancellationToken cancellationToken)
{
...
}
}
【问题讨论】:
-
不要公开公共构造函数,而是公开工厂方法。 (就此而言,如果您不希望代码调用公共函数,为什么它是公共的?它应该存在于其他地方吗?)
-
@AnthonyPegram,好主意。我还记得我可以做显式接口实现
async Task IWebSocketClient.ConnectAsync(CancellationToken cancellationToken),鼓励人们使用接口。 -
是的,如果该方法由接口声明,则显式实现适用于该方法,但您可能有意将其排除在接口定义之外。但是,如果您的意图是让该方法实际上仅通过界面可见,那么显式就是要走的路。
-
@AnthonyPegram,我也喜欢工厂方法。您是否建议
public static IWebSocketClient Create(Uri uri) => new WebSocketClient(uri);并制作构造函数internal? -
如果构造函数是内部的,那么程序集中的任何类都可以调用它,所以如果您打算在同一个程序集中使用该类(并且不希望直接构造),它应该是更受限制。从私有开始(意味着该类公开其自己的工厂方法)并从那里开始。