從字面上看,GetHRForException函數的作用很簡單:得到Exception所對應的HRESULT的值。但是,GetHRForException還會做一件事情:設定當前線程的IErrorInfo使之指向該Exception(嚴格來說是獲得Exception的CCW中的IErrorInfo介面指標)。如果對IErrorInfo不熟悉的朋友們可以把IErrorInfo看成COM版本的GetLastError或者errno。設定IErrorInfo會導致之後的代碼如果使用GetErrorInfo查詢IErrorInfo的值,會獲得一個非0的結果,那麼有些代碼可能會認為程式出錯而拒絕繼續執行。更糟糕的是,如果之後的代碼在做COM Interop或者PInvoke,CLR會檢查IErrorInfo,如果IErrorInfo非0則認為該調用失敗,並拋出異常或者返回錯誤值(視乎PreserveSigAttribute是否存在)。直接的結果是可能函數調用成功,但是因為IErrorInfo已經被設定而導致該調用最終失敗。很有意思的是在.NET中有一段處理資源的代碼正好有這個問題,結果間接導致了巴西葡萄牙語版本(是的,你沒看錯J)的.NET的RegAsm掛掉。其實我個人認為這個函數應該被命名為GetHRForExceptionAndSetIErrorInfo(Exception ex);雖然有些長,但是很清晰,總比簡短而錯誤的名字要來的好。
在正常情況下,如果你需要獲得Exception的HRESULT值,應該直接使用Exception.HResult屬性。那麼什麼時候才應該使用GetHRForException呢?當你寫了一個.NET的函數準備讓Unmanaged 程式碼調用(最好是通過COM),並且返回一個HRESULT,這個時候你有必要把託管函數內部拋出的異常轉換為HR,並且把Exception本身的資訊設定到當前線程的IErrorInfo中去,這才是最符合COM規範的。