2011-06-02 114 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; 
} 

這是做你所需要的嗎?我對你的需求有些模糊。