自定义的泛型类和泛型约束

自定义的泛型类和泛型约束
现在继续考虑Order,在企业中订单有很多种,运输单、出库单、外借单、报关单等等。因此应该把Order作为基类,然后其他订单从该类派生。
现在我们再看一下用户业务流程:当不同的用户角色创建了不同的订单,然后系统将这些订单汇总到公司的审计部,当审计通过后,订单将转向各自需要处理的业务部门。
为了实现这个方案,我们在Order声明了一个Send方法。
1None.gifpublicclassOrder
2ExpandedBlockStart.gifContractedBlock.gifdot.gif{
3InBlock.gifpublicstringOrderID;
4InBlock.gifpublicreadonlyDateTimeCreateDate=DateTime.Now;
5InBlock.gifpublicvirtualvoidSend()
6ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{System.Console.WriteLine("Order");}
7ExpandedBlockEnd.gif}

由于Send声明为virtual的,所以为其子类的各订单提供了多态的行为。
1None.gifpublicclassConsignationBill:Order
2ExpandedBlockStart.gifContractedBlock.gifdot.gif{
3InBlock.gifpublicoverridevoidSend()
4ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
5InBlock.gifSystem.Console.WriteLine("ConsignationBill");
6ExpandedSubBlockEnd.gif}

7ExpandedBlockEnd.gif}

8None.gifpublicclassDispatchBill:Order
9ExpandedBlockStart.gifContractedBlock.gifdot.gif{
10InBlock.gifpublicoverridevoidSend()
11ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
12InBlock.gifSystem.Console.WriteLine("DispatchBill");
13ExpandedSubBlockEnd.gif}

14ExpandedBlockEnd.gif}

15None.gifpublicclassWarehouseBill:Order
16ExpandedBlockStart.gifContractedBlock.gifdot.gif{
17InBlock.gifpublicoverridevoidSend()
18ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
19InBlock.gifSystem.Console.WriteLine("WarehouseBill");
20ExpandedSubBlockEnd.gif}

21ExpandedBlockEnd.gif}
现在考虑一个很实际的处理问题,当审计部门通过了订单的审核,需要执行Send方法,以便将订单转到业务相应的部门。那我们希望有一个类来处理对审核后的订单的任务传递
1None.gifpublicclassAudit
2ExpandedBlockStart.gifContractedBlock.gifdot.gif{
3InBlock.gifprivatereadonlyOrdertmpOrder;
4InBlock.gifpublicAudit(Orderorder)
5ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
6InBlock.giftmpOrder=order;
7ExpandedSubBlockEnd.gif}

8InBlock.gifpublicvoidAuditTask()
9ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
10InBlock.giftmpOrder.Send();
11ExpandedSubBlockEnd.gif}

12ExpandedBlockEnd.gif}
测试一下
1None.gifnewAudit(newConsignationBill()).AuditTask();
2None.gifnewAudit(newDispatchBill()).AuditTask();
3None.gifnewAudit(newWarehouseBill()).AuditTask();

通过了,效果不错。
现在考虑更多情况,Send很明显是用于业务流转的方法,除了订单,其他业务数据也会有流转的要求,为了统一,很显然,应该用到接口
1None.gifpublicinterfaceISend
2ExpandedBlockStart.gifContractedBlock.gifdot.gif{
3InBlock.gifvoidSend();
4ExpandedBlockEnd.gif}
更特别的是,不是所有的单据都有业务流转的行为,所有不能让Order去实现ISend接口,而是由Order的各子类去按实际情况分别实现ISend。
所以刚才的类的实现为
1None.gifpublicclassConsignationBill:Order,ISend
2ExpandedBlockStart.gifContractedBlock.gifdot.gif{
3InBlock.gifpublicvoidSend()
4ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
5InBlock.gifSystem.Console.WriteLine("ConsignationBill");
6ExpandedSubBlockEnd.gif}

7ExpandedBlockEnd.gif}

8None.gifpublicclassDispatchBill:Order,ISend
9ExpandedBlockStart.gifContractedBlock.gifdot.gif{
10InBlock.gifpublicvoidSend()
11ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
12InBlock.gifSystem.Console.WriteLine("DispatchBill");
13ExpandedSubBlockEnd.gif}

14ExpandedBlockEnd.gif}

15None.gifpublicclassWarehouseBill:Order,ISend
16ExpandedBlockStart.gifContractedBlock.gifdot.gif{
17InBlock.gifpublicvoidSend()
18ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
19InBlock.gifSystem.Console.WriteLine("WarehouseBill");
20ExpandedSubBlockEnd.gif}

21ExpandedBlockEnd.gif}
现在我们如果要求Audit能够正常调用Send的方法,那Audit的实现为
1None.gifpublicclassAudit
2ExpandedBlockStart.gifContractedBlock.gifdot.gif{
3InBlock.gifprivatereadonlyISendsender;
4InBlock.gifpublicAudit(ISendSender)
5ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
6InBlock.gifsender=Sender;
7ExpandedSubBlockEnd.gif}

8InBlock.gifpublicvoidAuditTask()
9ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
10InBlock.gifSystem.Console.WriteLine(sender.GetType().ToString());
11InBlock.gifsender.Send();
12ExpandedSubBlockEnd.gif}

13ExpandedBlockEnd.gif}
ok,虽然修改了Audit,但对调用者完全没有影响。那还有新的要求吗?有!
现在Audit类能接受所有实现了ISend的类,现在要求更严谨的处理:Audit类只能处理Order的子类,且该子类必须实现了ISend的接口。
晕啊,怎么写啊?使用反射帮忙
1None.gifpublicclassAudit
2ExpandedBlockStart.gifContractedBlock.gifdot.gif{
3InBlock.gifprivatereadonlyISendsender;
4InBlock.gifpublicAudit(ISendSender)
5ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
6InBlock.gifsender=Sender;
7ExpandedSubBlockEnd.gif}
8InBlock.gifpublicvoidAuditTask()
9ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
10InBlock.gifif(sender.GetType().BaseType.Name=="Order")
11ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
12InBlock.gifSystem.Console.WriteLine(sender.GetType().BaseType.Name);
13InBlock.gifSystem.Console.WriteLine(sender.GetType().ToString());
14InBlock.gifsender.Send();
15ExpandedSubBlockEnd.gif}

16ExpandedSubBlockEnd.gif}

17ExpandedBlockEnd.gif}
那能不能代码更简洁简单呢?可以,用泛型的约束能力
1None.gifpublicclassTAudit<T>whereT:Order,ISend
2ExpandedBlockStart.gifContractedBlock.gifdot.gif{
3InBlock.gifprivatereadonlyTsender;
4InBlock.gifpublicTAudit(TSender)
5ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
6InBlock.gifsender=Sender;
7ExpandedSubBlockEnd.gif}

8InBlock.gifpublicvoidAuditTask()
9ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif{
10InBlock.gifSystem.Console.WriteLine(sender.GetType().BaseType.Name);
11InBlock.gifSystem.Console.WriteLine(sender.GetType().ToString());
12InBlock.gifsender.Send();
13ExpandedSubBlockEnd.gif}

14ExpandedBlockEnd.gif}

以上说明该泛型能接受的对象是从Order继承,且实现了ISend接口,实例化的代码为
1None.gifnewTAudit<ConsignationBill>(newConsignationBill()).AuditTask();
2None.gifnewTAudit<DispatchBill>(newDispatchBill()).AuditTask();
3None.gifnewTAudit<WarehouseBill>(newWarehouseBill()).AuditTask();
使用泛型的约束,能让代码更加的清晰和简单。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值