C#基于接口的代码如何实现编译时具体类支持?
API客户端命令调用的类型安全与简洁性平衡
我被这个问题困扰了数周,简化后的场景如下:现有ApiClient类型的API客户端可发送带参数、返回数据的命令,希望用户调用SendCommand时无需强制转换,就能获得具体返回类型,且具备编译时检查与智能提示。
现有命令类结构
现有20个类似如下的命令类:
class AddCommand { class Args {} class Data {} } class ListCommand { class Args {} class Data {} } // 其余18个命令类结构类似...
期望调用方式
期望用户代码可这样调用,且对返回的data有智能提示和编译时检查:
AddCommand.Data data = apiClient.SendCommand(addCmdArgs);
已尝试的四种方案
方案1:基于具体类型重载
为每个命令在ApiClient中实现对应的SendCommand重载,用户端调用简洁,但新增命令时必须同步新增重载,维护繁琐且容易出错。
public AddCommand.Data SendCommand(AddCommand.Args args) { ... } public ListCommand.Data SendCommand(ListCommand.Args args) { ... } // 为所有20个命令重复上述代码...
方案2:单一接口方法
让命令、参数、数据分别实现对应接口,仅需一个SendCommand方法,库的扩展性好,但用户需要强制转换返回值,容易出现运行时错误。
命令类定义:
class AddCommand : ICommand { class Args : ICommandArgs {} class Data : ICommandData {} } class ListCommand : ICommand { class Args : ICommandArgs {} class Data : ICommandData {} } // 其余命令类类似...
ApiClient方法:
ICommandData SendCommand(ICommandArgs args) {}
方案3:两个无关泛型参数
使用泛型SendCommand方法,但用户需要手动指定两个无绑定的类型参数,容易出现参数不匹配的运行时错误。
TData SendCommand<TArgs, TData>(TArgs args) { ... } // 或者添加接口约束 TData SendCommand<TArgs, TData>(TArgs args) where TArgs : ICommandArgs where TData : ICommandData { ... }
方案4:三个关联泛型参数
通过接口绑定命令、参数、数据类型,确保编译时类型安全,但用户调用时需要指定三个类型参数,代码冗长。
接口定义:
interface ICommand<TArgs, TData> where TArgs : ICommandArgs where TData : ICommandData {} interface ICommandArgs {} interface ICommandData {}
命令类实现:
class AddCommand : ICommand<AddCommand.Args, AddCommand.Data> { class Args : ICommandArgs {} class Data : ICommandData {} } class ListCommand : ICommand<ListCommand.Args, ListCommand.Data> { class Args : ICommandArgs {} class Data : ICommandData {} } // 其余命令类类似...
ApiClient方法:
TData SendCommand<TCommand, TArgs, TData>(TArgs args) where TCommand : ICommand<TArgs, TData> where TArgs : ICommandArgs where TData : ICommandData { ... }
问题
目前我使用方案1,但希望找到兼顾用户端简洁性与库扩展性的更优方案,是否存在其他技术或设计模式可以解决这个问题?
内容的提问来源于stack exchange,提问作者Deepesh Choudhary
相关产品推荐
相关产品推荐

