2010-04-08 16 views
2

這個問題是關於「is」 and 「as」 in casting and about CA1800 PostSharp rule。我想知道我認爲的解決方案是否是最好的解決方案,或者是否有任何我看不到的問題。修復「PostSharp抱怨CA1800:DoNotCastUnnecessarily」是否最好?

我有這個代碼(命名爲OriginaL代碼,並減少到最小相關)。函數ValidateSubscriptionLicenceProducts試圖驗證一個SubscriptionLicence(可以是3種類型:Standard,Credit和TimeLimited),方法是轉換它並稍後檢查一些東西(在// Do Do Whatever中)。

PostSharp抱怨CA1800:DoNotCast無需。原因是我將兩次相同的對象投射到相同的類型。在最佳情況下,此代碼將投2次(如果它是StandardLicence),最壞情況下投4次(如果是TimeLimited許可證)。我知道可以使規則無效(這是我的第一種方法),因爲這裏對性能沒有太大影響,但我正在嘗試一種最佳方法。

//Version Original Code 
    //Min 2 casts, max 4 casts 
    //PostSharp Complains about CA1800:DoNotCastUnnecessarily 
    private void ValidateSubscriptionLicenceProducts(SubscriptionLicence licence) 
     { 
    if (licence is StandardSubscriptionLicence) 
      {    
       // All products must have the same products purchased 
       List<StandardSubscriptionLicenceProduct> standardProducts = ((StandardSubscriptionLicence)licence).SubscribedProducts; 
       //Do whatever 
      } 
      else if (licence is CreditSubscriptionLicence) 
      {    
       // All products must have a valid Credit entitlement & Credit interval 
       List<CreditSubscriptionLicenceProduct> creditProducts = ((CreditSubscriptionLicence)licence).SubscribedProducts; 
       //Do whatever 
      } 
      else if (licence is TimeLimitedSubscriptionLicence) 
      {     
       // All products must have a valid Time entitlement 
       // All products must have a valid Credit entitlement & Credit interval 
       List<TimeLimitedSubscriptionLicenceProduct> creditProducts = ((TimeLimitedSubscriptionLicence)licence).SubscribedProducts; 
       //Do whatever 
      } 
      else 
       throw new InvalidSubscriptionLicenceException("Invalid Licence type"); 

    //More code... 


     } 

這是使用「爲」Improved1版本。不要抱怨CA1800但問題是,它總是會施放3次(如果在將來,我們有30種或40個類型的許可證就可以執行壞)

//Version Improve 1 
    //Minimum 3 casts, maximum 3 casts 
    private void ValidateSubscriptionLicenceProducts(SubscriptionLicence licence) 
     { 
     StandardSubscriptionLicence standardLicence = Slicence as StandardSubscriptionLicence; 
      CreditSubscriptionLicence creditLicence = Clicence as CreditSubscriptionLicence; 
      TimeLimitedSubscriptionLicence timeLicence = Tlicence as TimeLimitedSubscriptionLicence; 

    if (Slicence == null) 
      {    
       // All products must have the same products purchased 
       List<StandardSubscriptionLicenceProduct> standardProducts = Slicence.SubscribedProducts; 
       //Do whatever 
      } 
      else if (Clicence == null) 
      {    
       // All products must have a valid Credit entitlement & Credit interval 
       List<CreditSubscriptionLicenceProduct> creditProducts = Clicence.SubscribedProducts; 
       //Do whatever 
      } 
      else if (Tlicence == null) 
      {     
       // All products must have a valid Time entitlement 
       // All products must have a valid Credit entitlement & Credit interval 
       List<TimeLimitedSubscriptionLicenceProduct> creditProducts = Tlicence.SubscribedProducts; 
       //Do whatever 
      } 
      else 
       throw new InvalidSubscriptionLicenceException("Invalid Licence type"); 

    //More code... 
     } 

但後來我想在最好的一個。這是我正在使用的最終版本。

//Version Improve 2 
// Min 1 cast, Max 3 Casts 
// Do not complain about CA1800:DoNotCastUnnecessarily 
private void ValidateSubscriptionLicenceProducts(SubscriptionLicence licence) 
     { 
      StandardSubscriptionLicence standardLicence = null; 
      CreditSubscriptionLicence creditLicence = null; 
      TimeLimitedSubscriptionLicence timeLicence = null; 

      if (StandardSubscriptionLicence.TryParse(licence, out standardLicence)) 
      { 
       // All products must have the same products purchased 
       List<StandardSubscriptionLicenceProduct> standardProducts = standardLicence.SubscribedProducts; 
    //Do whatever 
      } 
      else if (CreditSubscriptionLicence.TryParse(licence, out creditLicence)) 
      { 
       // All products must have a valid Credit entitlement & Credit interval 
       List<CreditSubscriptionLicenceProduct> creditProducts = creditLicence.SubscribedProducts; 
       //Do whatever 
      } 
      else if (TimeLimitedSubscriptionLicence.TryParse(licence, out timeLicence)) 
      { 
       // All products must have a valid Time entitlement 
       List<TimeLimitedSubscriptionLicenceProduct> timeProducts = timeLicence.SubscribedProducts; 
       //Do whatever 
      } 
      else 
       throw new InvalidSubscriptionLicenceException("Invalid Licence type"); 

      //More code... 

     } 


    //Example of TryParse in CreditSubscriptionLicence 
    public static bool TryParse(SubscriptionLicence baseLicence, out CreditSubscriptionLicence creditLicence) 
     { 
      creditLicence = baseLicence as CreditSubscriptionLicence; 
      if (creditLicence != null) 
       return true; 
      else 
       return false; 
     } 

它需要的類StandardSubscriptionLicence,CreditSubscriptionLicence和TimeLimitedSubscriptionLicence的改變有一個「的TryParse」方法(在下面的代碼複製)。這個版本我認爲它會投出最低只有一次,最多三次。 你對改進2有什麼看法?有沒有最好的方法呢?

回答

4

在你的三個代碼片段中,「提高2」似乎是最好的一個。 但是我認爲你可以通過完全消除鑄造需求的方式來改進設計。

將名爲ValidateProducts的抽象方法添加到SubscriptionLicence,並讓每個子許可證實現特定於該特定類型許可證的邏輯。這樣,您將業務邏輯與數據放在一起,從而避免了anemic domain model

這樣,你的方法的實現只會是:

private void ValidateSubscriptionLicenceProducts(SubscriptionLicence licence) 
{ 
    if(!licence.ValidateProducts()) 
     throw new Exception("Failed to validate products"); 
} 

此外,通過在基類中的方法抽象的,你執行每個「子牌」,落實方法,讓你做不需要檢查任何東西。因此,即使未來添加新類型的許可證,也永遠不需要更改ValidateSubscriptionLicenceProducts方法。

希望它是有道理的。

+0

這真是個好主意...... – 2010-04-09 12:55:54

0

我不認爲PostSharp抱怨。相當FxCop。