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設計は的外れです。

4

2 に答える 2

1

これはコンストラクター呼び出しとは実際には何の関係もないと思います。問題は、あるタイプのオブジェクトを別のタイプにキャストしようとしていることです。ユーザー定義の変換が含まれていない限り、コンストラクターが呼び出されることはありません(関連する2つのタイプが同じ継承階層にある場合はできません)。

より派生したタイプの新しいオブジェクトを作成する場合は、先に進んでください。

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編集:コレクションの内容は変更できないと思います。最初に適切なタイプのオブジェクトが含まれていることを確認できれば、それはすばらしいことです。含まれていない場合は、後で新しいオブジェクトを作成する必要があります。

于 2009-07-29T09:24:27.843 に答える
1

問題は、デバイスを_devicesコレクションに追加する方法にある可能性があります。

例えば:

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

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

Jon Skeetの例を参照すると、使用する必要があります

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

後でoをFileStreamオブジェクトにキャストする場合。

于 2009-07-29T09:33:55.747 に答える