Question

J'ai une liste d'objets de base (RTUDevice) et que vous souhaitez itérer et convertir chacun à un objet dérivé (en fait un dérivé d'un dérivé RTDSensor), mais le downcasting jette une erreur.

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

Serait-il préférable de passer l'objet de base dans un constructeur à RTDSensor comme

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

ou est ma conception OOP fourvoyés.

Était-ce utile?

La solution

Le problème pourrait être de la façon dont vous ajoutez les appareils à la collection _devices.

Par exemple:

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

devrait fonctionner. Toutefois, si vous ajoutez le capteur comme un objet RTUDevice vous ne pouvez pas le jeter à la suite RTDSensor parce qu'il ne dispose pas des informations supplémentaires qui porte RTDSensor.

En se référant à l'exemple de Jon Skeet vous devez utiliser

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

Si vous voulez plus tard jeter o à un objet FileStream.

Autres conseils

Je ne pense pas que cela ait vraiment rien à voir avec l'appel du constructeur - le problème est que vous essayez de jeter un objet d'un type à l'autre. Cela n'appelle un constructeur, à moins que vous avez une conversion définie par l'utilisateur concerné (que vous ne pouvez pas si les deux types sont impliqués dans la même hiérarchie d'héritage.)

Si vous voulez créer un nouveau objet du type plus dérivé, allez-y:

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

Si vous voulez convertir tous les objets, ce qui est un List<RTUDevice> alors vous pourriez utiliser:

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

ou plus approche fondée LINQ:

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

... mais vous ne pouvez pas dire .NET pour traiter un objet comme si elle était un type plus spécifique qu'il est en réalité. Pour-il à une longueur ridicule, qu'est-ce que vous attendez ce faire:

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

EDIT: Je suis supposé que vous ne pouvez pas changer ce qui est dans la collection _devices. Si vous pouvez vous assurer qu'il contient des objets du type approprié pour commencer, c'est super -. Sinon, vous devrez créer les nouveaux objets plus tard

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top