Domanda

Ho una lista di oggetti di base (RTUDevice) e voglia di scorrere e convertire ogni a un oggetto derivato (in realtà un derivato di un derivato RTDSensor), tuttavia la downcasting sta gettando un errore.

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);

Sarebbe meglio passare l'oggetto di base in un costruttore di RTDSensor come

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

o è il mio modo di progettazione OOP il marchio.

È stato utile?

Soluzione

Il problema potrebbe essere con il modo in cui si sta aggiungendo i dispositivi per la raccolta _devices.

Ad esempio:

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

dovrebbe funzionare. Tuttavia, se si aggiunge il sensore come un oggetto RTUDevice non puoi lanciare a RTDSensor poi perché non dispone delle informazioni supplementari che RTDSensor porta.

In riferimento all'esempio di Jon Skeet è necessario utilizzare

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

Se in seguito si vuole lanciare o ad un oggetto FileStream.

Altri suggerimenti

Non credo che questo ha davvero nulla a che fare con la chiamata al costruttore - il problema è che si sta cercando di lanciare un oggetto di un tipo all'altro. Che non chiama mai un costruttore, a meno che non hai una conversione definita dall'utente coinvolti (che non è possibile se i due tipi coinvolti sono nella stessa gerarchia di ereditarietà.)

Se si desidera creare un nuovo oggetto del tipo più derivata, via libera:

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

Se si desidera convertire tutti gli oggetti, e questo è un List<RTUDevice> allora si potrebbe usare:

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

o il più approccio LINQ-based:

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

... ma non si può certo dire .NET per il trattamento di un oggetto come se fosse un tipo più specifico di quello che effettivamente è. Per portarlo ad una lunghezza ridicola, che cosa ci si può aspettare questo per fare:

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

EDIT: Ho pensato che non si può cambiare ciò che è nella collezione _devices. Se si riesce a fare in modo che esso contiene oggetti del tipo appropriato per cominciare, che è grande -. In caso contrario, è necessario creare i nuovi oggetti in seguito

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top