2011-12-16 67 views
1

我正在开发与外部设备通信的软件。该设备需要一组初始化值(calibrationData)。这些设备的校准数据有所不同。在第一个版本中,校准数据可以由用户选择,因此用户可能会意外加载在不同部件上获得的校准数据。该设备将工作,但将不正确的措施。 我在构造函数结束时抛出异常是否会损坏对象?

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. 
    } 

,然后其他

try 
{ 
    instrument = new Instrument(calibration); 
} 
catch (WrongCalibrationException e) 
{ 
    MessageBox.Show("You tried to load calibration obtained on different device."); 
} 

地方我不能够检查ID我连接到设备前。

这个问题其实包含两个。

  1. 我的解决方案是否正确?我想自动测试正确校准的用法,而不依赖于程序员使用我的代码调用另一种方法(类似Instrument.AreYouProperlyCalibrated())

  2. 当在最后抛出异常时正确构造对象的构造函数?我有点担心C#在construcor完成之后正在做一些巨型巨无霸,而且在ctor抛出异常的情况下这可能会有所不同。

感谢

+0

Marc和Yuriy几乎涵盖了我所想的一切。我只是补充说,即使构造函数没有完全完成,任何您为该类提供的终结器仍将运行,因此请注意终结器中(您似乎没有看到)。 – 2011-12-16 08:24:00

回答

3

实例已经完全存在在构造函数开始之前存在(实际上,甚至可以完全绕过所有构造函数并仍然获得有效实例) - 这仅表示任何未执行的初始化代码都不会执行。

例如,而这是不是一个好主意,您可以在构造函数的过程传递对象实例出的类型,即

_camera.HereIsMe(this); 

SomeExternalObject.Track(this); 

所以没有什么可怕的事情会发生,因为就运行时而言,这个对象像普通一样存在,并且必须正确处理。然而,在某些情况下它是清洁剂使用工厂:

public static YourType Create(args) { 
    // TODO: perform enough work to validate 
    return new YourType(validated args); 
} 

但重申;如果存在问题,则从构造函数中抛出并不意外,并且无害。

+0

如果所讨论的对象实现了IDisposable,那么将一个实例从一个`protected`构造函数中传递出来(使其可用于工厂方法)可能是一个非常好的主意。包装构造函数的工厂方法可以在部分构建的对象上调用Dispose。当然,Dispose例程必须被编写来处理这种可能性,但是对于派生类来说,模式看起来比在每个构造函数中放置“try”块更清晰。 – supercat 2011-12-16 17:42:13

2

它喜好的问题。例如,DateTime在其constructor中引发异常。如果你不想,你可以使用静态方法,如Build(Calibration calibration)。一个好的做法是使用XML注释让您的类型的用户知道构造函数在<exception>标记中抛出异常。

2

您可以从代码中的任何位置抛出异常。

如果你的构造函数在某处抛出,并且抛出,则不会创建该对象,或者为了更加正确,它将被创建,但是你的代码执行流将遵循该异常,所以你不会在创建对象的代码分支中,所以它就像它根本就没有被创建,因为你关心的是什么。

所以我会说你的方法,只考虑你发布的代码,是好的。显然,可能存在其他与CameraDriver构造函数(未放置的东西等)有关的问题,但这是另一回事。

0

我谨指出,摄像头和驱动程序对象应该得到添加到马克的回答注入课堂。看到这个(许多之一)文章(S)implementing Dependency Injection in C#

希望我不会因为这是一个意见而受到鞭打。 ;)

相关问题