I’m working on a software communicating with external device. The device requires a set of initialization values (calibrationData). Those calibration data differ from piece to piece of this equipment. In first versions the calibrationData can be selected by user and thus the user may by accident load calibrationData obtained on different piece. The device would work, but will measure incorrectly.
I have
public Instrument(CalibrationData calibration)
{
_camera = new Camera();
_driver = new Driver();
if (_camera.GetUniqueId() != calibration.GetCameraUniqueId())
throw new WrongCalibrationException("Calibration file was obtained on different equipment.");
//Don't write anything here. Exception has to be the last code in the constructor.
}
and then somewhere else
try
{
instrument = new Instrument(calibration);
}
catch (WrongCalibrationException e)
{
MessageBox.Show("You tried to load calibration obtained on different device.");
}
I’m not able to check the ID before I’m connected to the device.
This question comprises out of two in fact.
-
Is my solution correct? I want to test usage of proper calibration automatically and not rely on the programmer using use my code to call another method (Something like Instrument.AreYouProperlyCalibrated())
-
Is the object constructed properly when the exception is thrown at the end of constructor? I’m a bit afraid that C# is doing some mumbo jumbo after the construcor finishes and that this might be different in case the ctor threw an exception.
Thanks
The instance already fully exists before the constructor begins (indeed, you can even completely bypass all constructors and still get a valid instance) – it just means that any initialization code that didn’t execute won’t have executed.
For example, while it isn’t a good idea, you can pass the object instance out of the type during the constructor, i.e.
or
so nothing too terrible will happen, since as far as the runtime is concerned this object exists like normal, and must be handled properly. However, in some cases it is cleaner to use a factory:
But to reiterate; if there is a problem, then throwing from the constructor is not unexpected and is not harmful.