2009-07-29 23 views
2

我有一個基礎對象(RTUDevice)的列表,並且想要遍歷並將其轉換爲派生對象(實際上派生了派生的RTDSensor),但是向下轉換會引發錯誤。構造函數中的基礎對象作爲向下傾斜的替代

public RTUDevice(int id) 
{ 
    _id = id; 
} 

public class RTDDevice : RTUDevice 
{ 
    public RTDDevice(int id) 
     : base(id) 
    { 

    } 
} 

public class RTDSensor : RTDDevice 
{ 
    public RTDSensor(int id) 
     : base(id) 
    { 

    } 
} 

RTDSensor return = (RTDSensor)_devices.Find(d => d.Id == p.ReturnId); 

它會更好,以在構造函數傳遞基礎對象RTDSensor像

public RTDSensor(RTUDevice rtu) : base(rtu.Id) 
{ 
} 

或者是我的OOP設計沒譜的方式。

+0

是否有一些ORM參與(看起來像有)? Find方法是做什麼的?拋出的異常是什麼?你確定你的p.ReturnId是一個RTDSensor嗎? – Mac 2009-07-29 09:24:58

回答

1

問題可能出在您將設備添加到_devices集合的方式。

例如:

RTDSensor sensor = new RTDSensor(1); 
_devices.Add(sensor); 
RTDSensor retrievedSensor = (RTDSensor)_devices.Find(d => d.Id == 1); 

應該工作。但是,如果將傳感器添加爲RTUDevice對象,則以後無法將其轉換爲RTDSensor,因爲它沒有RTDSensor攜帶的附加信息。

參考喬恩斯基特的例子中,你必須使用

object o = new FileStream(path, filemode); 
FileStream fs = (FileStream)o; 

如果以後要投O操作FileStream對象。

1

我不認爲這真的與構造函數調用有任何關係 - 問題是你正試圖將一種類型的對象轉換爲另一種類型的對象。除非您有涉及用戶定義的轉換(如果涉及的兩種類型處於相同的繼承層次結構中,則不能這樣做)。

如果要創建新對象對象更多的派生型,前進:

RTUDevice device = _devices.Find(d => d.Id == p.ReturnId); 
RTDSensor sensor = new RTDSensor(device); // Or whatever 

如果要轉換所有的對象,這是一個List<RTUDevice>那麼你可以使用:

List<RTDSensor> sensors = _devices.ConvertAll(device => new RTDSensor(device)); 

或更多的基於LINQ的方法:

IEnumerable<RTDSensor> x = _devices.Select(device => new RTDSensor(device)); 

...但你不能只是告訴.NET治療的對象,就好像它是一個更具體的類型比實際的。爲了把它帶到一個荒謬的長度,你會想到這是什麼做的:

object o = new object(); 
FileStream fs = (FileStream) o; 
rs.ReadByte(); // Where from? 

編輯:我認爲你不能改變什麼是_devices收藏。如果您可以確保它包含適當類型的對象,那很好 - 如果不是,那麼您需要稍後創建新對象。

+0

我想你錯過了將正確類型的對象添加到集合中的問題,這比將「基礎」對象傳遞給「派生」對象的構造函數要簡單得多。 – chrischu 2009-07-29 09:36:49

+0

你假設他可以改變集合的構建方式。我試圖解決我懷疑的一個更基本的誤解:OP相信cast會通過調用構造函數來創建一個新對象。 – 2009-07-29 09:37:40

相關問題