Combine two methods with different input and output parameters into one method through an alternative generic constraint.
In fact, I don't know how to define this title. I have no words. Let's define it first.
If you have read a better title, please let me know. Thank you.
This problem occurs when you use the SDK for a project.
This SDK has a BtPrinterManager class and has two methods: ServerPrint and ClientPrint,Some of the two methods have the same parameters, and some of them have different parameters..
Now we want to encapsulate this class,Combine these two methods into one, and make them have the same input and output parameters..
The rough way is to combine the input parameters of the two methods into an input model class, and combine the output parameters of the two methods into an output model class.
By adding a parameter or determining whether a method exclusive parameter has a value, you can decide whether to call ServerPrint or ClientPrint within the method, and which parameters should be obtained from the input model class, which values should be assigned to the output model class.
If I do not follow the above practice, what else can I do?
The answer is yes. Generic constraints + methods are used to determine the actual type of generics.
The following is the implementation code:
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 object assignment .... 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 // assign values to the serverInputModel object .... 25 Action <ServerOutputModel> serverAction = info => {Console. writeLine (info. printerName +Info. ServerName) ;}; 26 serverManager. print (serverInputModel, serverAction ); 27} 28} 29 30 // <summary> 31 // print management class 32 // </summary> 33 public abstract class PrinterManager 34 {35 // <summary> 36 // print file 37 // </summary> 38 // <typeparam name = "TInputModel"> </typeparam> 39 // <typeparam name = "TOutputModel "> </typeparam> 40 // <param name =" model "> </param> 41 // <param name =" action "> </param> 42/ // <retu Rns> </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 // Client Print management class 48 /// </summary> 49 public class ClientPrinterManager: printerManager 50 {51 public override string Print <TInputModel, TOutputModel> (TInputModel mo Del, Action <TOutputModel> action) 52 {53 string message = string. Empty; 54 55 # region generic type check 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 here pretend to be the result obtained by calling an SDK method 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 82TOutputModel result = (TOutputModel) Convert. ChangeType (info, typeof (TOutputModel ));83Action (result );84 85 return message; 86} 87} 88 89 // <summary> 90 // The server prints the management class 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 generic type verification 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 # endregion109 110 # region here it is assumed that the result obtained by calling an SDK method is 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 ServerOutputModel117 {118 PrinterName = "Test Printer", 119 ServerName = "Test Server" 120}; 121 message = "ServerPrint Success "; 122 123 # endregion124 125TOutputModel result = (TOutputModel) Convert. ChangeType (info, typeof (TOutputModel ));126Action (result );127 128 return message; 129} 130} 131 132 # region Input Model class 133 public class InputModelBase134 {135 public string Param1 {get; set;} 136 137 public string Param2 {get; set;} 138} 139 140 public class ClientInputModel: InputModelBase141 {142 public string ClientParam1 {get; set;} 143} 144 145 public class ServerInputModel: InputModelBase146 {147 public string ServerParam1 {get; set;} 148 149 150 public string ServerParam2 {get; set;} 151} 153 # endregion152 154 # region output model class 156 public class OutputModelBase155 {public string PrinterName {get; set ;} 157} 158 159 public class ClientOutputModel: OutputModelBase160 {161 public string ClientName {get; set;} 162} 163 164 public class ServerOutputModel: OutputModelBase165 {166 public string ServerName {get; set ;} 167} 168 # endregion169}
If you have a better implementation method, please advise. Thank you.