2011-12-16 50 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#

希望我不會因爲這是一個意見而受到鞭打。 ;)

相關問題