2009-07-29 10 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); 

はマークオフ

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

かである私のOOPの設計方法のようにRTDSensorにコンストラクタでベースオブジェクトを渡す方が良いでしょう。

+0

ORMが関わっていますか(存在するようです)? Findメソッドは何をしますか?スローされた例外は何ですか? p.ReturnIdがRTDSensorであると確信していますか? – Mac

答えて

1

問題は、デバイスを_devicesコレクションに追加していることが原因です。例えば

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

が動作するはずです。しかし、センサーをRTUDeviceオブジェクトとして追加すると、RTDSensorが保持する追加情報がないため、後でそのセンサーをRTDSensorにキャストすることはできません。

あなたは後でFileStreamオブジェクトへのoをキャストしたい場合は

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

を使用する必要がジョンスキートの例を参照します。

+0

これは_devicesコレクションが基本型のリストであり、これに派生型を追加するのでしょうか? –

+0

共通の基本型を持つオブジェクトのコレクションを格納するのは、これが本当に一般的なアプローチです。しかし、RTDSensorメソッドをコレクション内のすべてのオブジェクトに対して使用する場合は、RTDSensorメソッドを毎回キャストするのではなく、RTDSensor型のコレクションにするほうが良いのはもちろんです。 – chrischu

+0

これは、ありがとうございます。アイテムはデータベースから来ており、私が今できるベースリストに基本情報を得たいと思っていました。 –

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

+0

コレクションの構成方法を変更できるとしています。私は、より基本的な誤解であると思われるものに取り組もうとしています:OPは、キャストがコンストラクタを呼び出すことによって新しいオブジェクトを作成すると信じています。 –

+0

変換について理解しています。私は新しいオブジェクトを使用し、コンストラクタで基本オブジェクトを渡します。 –

関連する問題