通过另类的泛型约束将两个输入输出参数不同的方法合并成一个方法的实现

 其实我也不知道如何定义这个标题,词乏,姑且先这样定义吧。

看了本文章的朋友,如果有更好标题,请告诉我,谢谢。

 

有个项目使用SDK时遇到这样一个情况。

该SDK有个BtPrinterManager类,拥有两个方法:ServerPrint和ClientPrint,这两个方法有一部分参数是一样的,一部分参数不一样

现在我们要对这个类进行封装,把这两个方法合并成一个方法,并且使其拥有相同的输入参数和输出参数

比较粗糙的做法是,把这两个方法的输入参数合并成一个输入模型类,把两个方法的输出参数也合并成一个输出模型类。

通过增加一个参数或(判断某个方法专属参数是否有值)在方法内部决定应该调用ServerPrint还是ClientPrint,以及应该从输入模型类里取哪些参数,应该赋哪些值给输出模型类。

如果不按照上面的做法写,还有什么办法可以做到呢?

答案是有的,泛型约束+方法内对泛型实际类型判断。

 

以下是实现代码:

  1 using System;
  2 
  3 namespace Test
  4 {
  5     internal class Program
  6     {
  7         private static void Main(string[] args)
  8         {
  9             Run();
 10             
 11             Console.ReadKey();
 12         }
 13 
 14         private static void Run()
 15         {
 16             PrinterManager clientManager = new ClientPrinterManager();
 17             ClientInputModel clientInputModel = new ClientInputModel();
 18             //clientInputModel对象赋值....
 19             Action<ClientOutputModel> clientAction = info => { Console.WriteLine(info.PrinterName + info.ClientName); };
 20             clientManager.Print(clientInputModel, clientAction);
 21 
 22             PrinterManager serverManager = new ServerPrinterManager();
 23             ClientInputModel serverInputModel = new ClientInputModel();
 24             //serverInputModel对象赋值....
 25             Action<ServerOutputModel> serverAction = info => { Console.WriteLine(info.PrinterName + info.ServerName); };
 26             serverManager.Print(serverInputModel, serverAction);
 27         }
 28     }
 29 
 30     /// <summary>
 31     /// 打印管理类
 32     /// </summary>
 33     public abstract class PrinterManager
 34     {
 35         /// <summary>
 36         /// 打印文件
 37         /// </summary>
 38         /// <typeparam name="TInputModel"></typeparam>
 39         /// <typeparam name="TOutputModel"></typeparam>
 40         /// <param name="model"></param>
 41         /// <param name="action"></param>
 42         /// <returns></returns>
 43         public abstract string Print<TInputModel, TOutputModel>(TInputModel model, Action<TOutputModel> action) where TInputModel : InputModelBase, new() where TOutputModel : OutputModelBase, new();
 44     }
 45 
 46     /// <summary>
 47     /// 客户端打印管理类
 48     /// </summary>
 49     public class ClientPrinterManager : PrinterManager
 50     {
 51         public override string Print<TInputModel, TOutputModel>(TInputModel model, Action<TOutputModel> action)
 52         {
 53             string message = string.Empty;
 54 
 55             #region 泛型类型校验
 56             if (typeof(TInputModel) != typeof(ClientInputModel))
 57             {
 58                 throw new ArgumentException($"{nameof(TInputModel)} generic types must be of type {nameof(ClientInputModel)}", nameof(ClientInputModel));
 59             }
 60 
 61             if (typeof(TOutputModel) != typeof(ClientOutputModel))
 62             {
 63                 throw new ArgumentException($"{nameof(TOutputModel)} generic types must be of type {nameof(ClientOutputModel)}", nameof(ClientOutputModel));
 64             }
 65             #endregion
 66 
 67             #region 这里假装是调用某SDK方法获取的结果
 68 
 69             //BtPrinter printer = new BtPrinter();
 70             //string message;
 71             //var info = printer.ClientPrint(model.Param1, model.Param2, model.Param1, model.ClientParam1, out message);
 72 
 73             var info = new ClientOutputModel
 74             {
 75                 PrinterName = "Test Printer",
 76                 ClientName = "Test Client"
 77             };
 78             message = "ClientPrint Success";
 79 
 80             #endregion
 81 
 82             TOutputModel result = (TOutputModel)Convert.ChangeType(info, typeof(TOutputModel));
 83             action(result);
 84 
 85             return message;
 86         }
 87     }
 88 
 89     /// <summary>
 90     /// 服务器端打印管理类
 91     /// </summary>
 92     public class ServerPrinterManager : PrinterManager
 93     {
 94         public override string Print<TInputModel, TOutputModel>(TInputModel model, Action<TOutputModel> action)
 95         {
 96             string message = string.Empty;
 97 
 98             #region 泛型类型校验
 99             if (typeof(TInputModel) != typeof(ServerInputModel))
100             {
101                 throw new ArgumentException($"{nameof(TInputModel)} generic types must be of type {nameof(ServerInputModel)}", nameof(ServerInputModel));
102             }
103 
104             if (typeof(TOutputModel) != typeof(ServerOutputModel))
105             {
106                 throw new ArgumentException($"{nameof(TOutputModel)} generic types must be of type {nameof(ServerOutputModel)}", nameof(ServerOutputModel));
107             }
108             #endregion
109 
110             #region 这里假装是调用某SDK方法获取的结果
111 
112             //BtPrinter printer = new BtPrinter();
113             //string message;
114             //var info = printer.ServerPrint(model.Param1, model.Param2, model.ServerParam1, model.ServerParam2, out message);
115 
116             var info = new ServerOutputModel
117             {
118                 PrinterName = "Test Printer",
119                 ServerName = "Test Server"
120             };
121             message = "ServerPrint Success";
122 
123             #endregion
124 
125             TOutputModel result = (TOutputModel)Convert.ChangeType(info, typeof(TOutputModel));
126             action(result);
127 
128             return message;
129         }
130     }
131 
132     #region 输入模型类
133     public class InputModelBase
134     {
135         public string Param1 { get; set; }
136 
137         public string Param2 { get; set; }
138     }
139 
140     public class ClientInputModel : InputModelBase
141     {
142         public string ClientParam1 { get; set; }
143     }
144 
145     public class ServerInputModel : InputModelBase
146     {
147         public string ServerParam1 { get; set; }
148 
149         public string ServerParam2 { get; set; }
150     }
151     #endregion
152 
153     #region 输出模型类
154     public class OutputModelBase
155     {
156         public string PrinterName { get; set; }
157     }
158 
159     public class ClientOutputModel : OutputModelBase
160     {
161         public string ClientName { get; set; }
162     }
163 
164     public class ServerOutputModel : OutputModelBase
165     {
166         public string ServerName { get; set; }
167     }
168     #endregion
169 }

 

如果有更好的方法实现,求指教,谢谢。

转载于:https://www.cnblogs.com/VAllen/p/Merge-methods-with-diff-parameters.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值