2011-07-08 64 views
1

我使用參數對象來封裝傳遞給我的業務規則的參數。該規則是使用上下文參數創建的,然後可以修改該參數,然後在稍後執行該規則。該對象的某些屬性是必需的,否則該方法將拋出一個NullReferenceException。但是,如果我拋出ArgumentNullException,我會收到警告,說明參數名稱與我的某個參數不匹配。這種情況適合的例外是什麼?當參數對象的必需屬性爲空時,應拋出哪個異常

public class GetAttributes : BusinessRuleBase 
{ 
    private readonly IGetAttributesContext _context; 


    public GetAttributes(IGetAttributesContext context) 
    { 
     _context = context; 
    } 

    public override void Execute() 
    { 
     if (_context.AttributeModel == null) 
     { 
      //Exception would be thrown here 
     } 
     _context.Attributes = _context.AttributeModel 
             .DoSomething(_context.EntityType); 
    } 
} 
+2

我建議使用代碼合同代替。 'ArgumentNullException'並不是很有用,因爲任何這種類型的catch都很可能代表一個bug。 –

+0

許多人認爲你永遠不應該拋出一個可以被系統自動提升的類型的異常 - 而'NullReferenceException'就是其中之一。 –

+1

爲什麼不'InvalidOperationException? –

回答

2

如果使用代碼契約,你願意公開揭露HasAttributeModel財產,我建議

Contract.Requires(this.HasAttributeModel); 

否則,你應該拋出一個由InvalidOperationException這裏派生自定義異常。給定對象的當前狀態,您嘗試執行的方法無效。從文檔:

當方法調用對於對象的當前狀態無效時引發的異常。

您的自定義消息應該說實例的AttributeModelnull

更大的問題是,爲什麼你允許你的實例處於可以在對象處於無效狀態時調用方法的狀態?如果可以的話,你應該避免這種情況。例如,爲什麼不檢查GetAttributes不是null?您可以有

Contract.Requires(context.AttributeModel != null); 

作爲此方法的先決條件。但是,如果某人保留對參數context的引用的實時引用,則可能會破壞狀態,因爲您通過私有變量_context維護引用。注意這一點,如果可以的話,避免它。

+1

自定義消息應該說實例的*'IGetAttributesContext'的*'AttributeModel'是'null'。 – StriplingWarrior

+0

這個想法是,在執行當前規則之前,上下文屬性的值可能受到其他業務規則的影響。這允許另一個規則在執行此規則之前設置類似於EntityType或AccountModel的內容。在這種情況下,我同意InvalidOperationException,因爲上下文參數是我的對象狀態的一部分。 –

+0

@瑞恩格羅斯:那種毛病。 – jason

-1

用您的自定義描述拋出NullReferenceException,或創建自己的自定義異常。

InvalidArgumentException說這個參數是無效的,但是在你的情況下沒有參數,而且對於無效或有效它必須是非空的。

+1

不,他沒有取消引用「null」對象引用。 – jason

0

您應該使用您的自定義異常來確保您確實能夠捕獲到您的異常,而不是系統生成的異常。

+0

不,在框架中已經有了一個非常有效的'Exception'派生類:'InvalidOperationException'。在這種情況下創建自定義異常違反了框架設計準則。 – jason

1

如果您認爲有人可能想要捕獲此特定異常並以與典型異常不同的方式處理它,請編寫您自己的異常類。

理想情況下,您可以通過檢查(命名不清的)GetAttributes方法中的此屬性來獲得快速失敗行爲。在這種情況下,如果你不使用自己的自定義異常類型,我會拋出一個ArgumentException

如果在早期檢查此屬性並且仍然想使用系統異常類型沒有意義,那麼Jason是正確的:使用InvalidOperationException

+0

該GetAttributes調用有一個構造函數(缺少返回類型是一個givaway)。爲了更加清晰,我已經更新了這個問題。我同意InvalidOperationException是最好的選擇,但我不會接受你的答案,因爲你很粗魯。 –

+1

@Ryan Gross:公平地說,GetAttributes類沒有很好地命名。 – jason

相關問題