2011-06-02 97 views
2

我在使用Table per Hierarchy设置和实体框架时设计服务层时遇到问题。我的问题是,我得到一个特定类型的对象,但我想检查类型是什么。这是更好的代码解释:了解抽象类的子类型

摘要域

public abstract class Order 
{ 
    public string OrderId { get; set; } 
} 

继承类

public class OrderProduct : Order 
{ 
    public List<OrderDetail> OrderDetails { get; set; } 
} 

public class OrderSubscription : Order 
{ 
    public decimal Fee { get; set; } 
    public DateTime? EndDate { get; set; } 
} 

所以你基本上可以做到这一点:

orderRepository.GetOrders(); 
//OR 
orderRepository.GetOrders().OfType<OrderProduct>(); 
//OR 
orderRepository.GetOrders().OfType<OrderSubscription>(); 

我'米巴斯使用第一个。它返回IQueryable<Order>

我要让1个服务层的方法,使该得到的任何类型,例如呼叫:

public Order GetOrder(string orderId) 
{ 
    return orderRepository.GetOrders().FirstOrDefault(o => o.OrderId == orderId); 
} 

的问题

在我的控制,我怎么能告诉在拨打电话GetOrder(string orderId)后,对象是什么类型?如果它属于OrderProduct类型,那么当我施放它时,我还需要导航属性(List<OrderDetail>)。

我看到的一个解决方案是为每个Order类创建2类服务层调用。调用1,如果它返回null,则调用另一个。但是有没有OOP方式在C#中做到这一点?

+0

关闭我的头顶,只是在抽象类和继承类中添加一个类型的道具设置它。或类似的东西。 – Terrance 2011-06-02 18:46:19

回答

2

我不能完全肯定你是问什么,但我认为你正在寻找is操作:

Order order = //...  
bool isSubscription = order is OrderSubscription; 

另外如果你想使用的值之后,你还可以使用as,这将投它或返回null它它不是这种类型。

Order order = //... 
OrderSubscription subscription = order as OrderSubscription; 
if (subscription != null) 
{ 
    // use subscription 
} 
+0

所以,即使我回到'Order',它仍然可以是'OrderSubscription'类型,我可以将它与所有不在基类中的属性一起进行投射。 – 2011-06-02 19:03:11

+0

是的。 'OrderSubscription'也是'Order','Order'也可以是'OrderSubscription'。 – 2011-06-02 19:10:15

+0

铸造不会更改对象的实际类型。 Cast实际上只是告诉编译器,这个变量应该是Order类型的,但是真正的对象是不变的 – MBen 2011-06-02 19:22:32

0
Order o = GetOrder("12345"); 
if (o is OrderProduct) 
{ 
    var product = (OrderProduct)o; 
} 
else if (o is OrderSubscription) 
{ 
    var subscription = (OrderSubscription)o; 
} 

这是做你所需要的吗?我对你的需求有些模糊。