自定义的泛型类和泛型约束
2007-03-19 16:39
260 查看
自定义的泛型类和泛型约束
现在继续考虑Order,在企业中订单有很多种,运输单、出库单、外借单、报关单等等。因此应该把Order作为基类,然后其他订单从该类派生。现在我们再看一下用户业务流程:当不同的用户角色创建了不同的订单,然后系统将这些订单汇总到公司的审计部,当审计通过后,订单将转向各自需要处理的业务部门。
为了实现这个方案,我们在Order声明了一个Send方法。
public class Order { public string OrderID; public readonly DateTime CreateDate = DateTime.Now; public virtual void Send() {System.Console.WriteLine("Order");} }
由于Send声明为virtual的,所以为其子类的各订单提供了多态的行为。
public class ConsignationBill : Order { public override void Send() { System.Console.WriteLine("ConsignationBill"); } } public class DispatchBill : Order { public override void Send() { System.Console.WriteLine("DispatchBill"); } } public class WarehouseBill : Order { public override void Send() { System.Console.WriteLine("WarehouseBill"); } }
现在考虑一个很实际的处理问题,当审计部门通过了订单的审核,需要执行Send方法,以便将订单转到业务相应的部门。那我们希望有一个类来处理对审核后的订单的任务传递
public class Audit { private readonly Order tmpOrder; public Audit(Order order) { tmpOrder = order; } public void AuditTask() { tmpOrder.Send(); } }
测试一下
new Audit(new ConsignationBill()).AuditTask();
new Audit(new DispatchBill()).AuditTask();
new Audit(new WarehouseBill()).AuditTask();
通过了,效果不错。
现在考虑更多情况,Send很明显是用于业务流转的方法,除了订单,其他业务数据也会有流转的要求,为了统一,很显然,应该用到接口
public interface ISend { void Send(); }
更特别的是,不是所有的单据都有业务流转的行为,所有不能让Order去实现ISend接口,而是由Order的各子类去按实际情况分别实现ISend。
所以刚才的类的实现为
public class ConsignationBill : Order,ISend { public void Send() { System.Console.WriteLine("ConsignationBill"); } } public class DispatchBill : Order, ISend { public void Send() { System.Console.WriteLine("DispatchBill"); } } public class WarehouseBill : Order, ISend { public void Send() { System.Console.WriteLine("WarehouseBill"); } }
现在我们如果要求Audit能够正常调用Send的方法,那Audit的实现为
public class Audit { private readonly ISend sender; public Audit(ISend Sender) { sender = Sender; } public void AuditTask() { System.Console.WriteLine(sender.GetType().ToString()); sender.Send(); } }
ok,虽然修改了Audit,但对调用者完全没有影响。那还有新的要求吗?有!
现在Audit类能接受所有实现了ISend的类,现在要求更严谨的处理:Audit类只能处理Order的子类,且该子类必须实现了ISend的接口。
晕啊,怎么写啊?使用反射帮忙
public class Audit { private readonly ISend sender; public Audit(ISend Sender) { sender = Sender; } public void AuditTask() { if (sender.GetType().BaseType.Name == "Order") { System.Console.WriteLine(sender.GetType().BaseType.Name); System.Console.WriteLine(sender.GetType().ToString()); sender.Send(); } } } 能不能代码更简洁简单呢?可以,用泛型的约束能力 public class TAudit<T> where T : Order, ISend { private readonly T sender; public TAudit(T Sender) { sender = Sender; } public void AuditTask() { System.Console.WriteLine(sender.GetType().BaseType.Name); System.Console.WriteLine(sender.GetType().ToString()); sender.Send(); } }
以上说明该泛型能接受的对象是从Order继承,且实现了ISend接口,实例化的代码为
new TAudit<ConsignationBill>(new ConsignationBill()).AuditTask();
new TAudit<DispatchBill>(new DispatchBill()).AuditTask();
new TAudit<WarehouseBill>(new WarehouseBill()).AuditTask();
使用泛型的约束,能让代码更加的清晰和简单。
相关文章推荐
- 自定义的泛型类和泛型约束
- 自定义的泛型类和泛型约束
- C# 泛型编程之泛型类、泛型方法、泛型约束
- C#泛型入门学习泛型类、泛型集合、泛型方法、泛型约束、泛型委托
- 泛型第一课,自定义泛型,泛型类,泛型接口,泛型的方法
- C# 泛型编程之泛型类、泛型方法、泛型约束
- 第五节:泛型(泛型类、接口、方法、委托、泛型约束、泛型缓存、逆变和协变)
- [置顶] C#泛型入门学习泛型类、泛型集合、泛型方法、泛型约束、泛型委托
- C# 泛型编程之泛型类、泛型方法、泛型约束
- C# 泛型编程之泛型类、泛型方法、泛型约束
- 自定义扩展方法(集合泛型约束)超好用,这里理解方法当参数来使用
- C# 泛型编程之泛型类、泛型方法、泛型约束
- paip.自定义java 泛型类与泛型方法的实现总结
- Java自定义泛型类和泛型方法
- paip.自定义java 泛型类与泛型方法的实现总结
- 用LinQ扩展方法,泛型扩展方法,实现自定义验证字符是否空、对象是否为null,及泛型约束使用,Action的使用
- 116_容器_自定义泛型_泛型类_泛型接口_泛型方法_安全_省心
- C# 自定义泛型类,并添加约束
- java 泛型 之自定义泛型类
- C# 泛型编程之泛型类、泛型方法、泛型约束