2013-01-02 44 views
3

当使用代码契约,我得到了警告:如何代码契约使用的TryParse没有得到警告

检测调用方法 “System.Int32.TryParse(System.String,System.Int32 @)”没有方法

具有与像下面的代码的inteface定义的接口和代码合同一类 合同[纯]。问题是如何检查字符串orgNumberWithoutControlDigit可以转换为一个有效的整数,因为它是模数工作的先决条件?

public string getControlDigit(string orgNumberWithoutControlDigit) 
    { 
     List<int> orgNumberNumbers = this.getNumberList(orgNumberWithoutControlDigit); 

     List<int> productList = orgNumberNumbers.Zip(this.weightNumberList, (first, second) => first * second).ToList(); 

     int modular = productList.Sum() % 11; 

     string controlDigit = getControlDigit(modular); 

     return controlDigit; 
    } 

private static string getControlDigit(int modular) 
    { 
     string controlDigit; 


     if (modular == 0) 
     { 
      controlDigit = "0"; 
     } 
     else if (modular == 1) 
     { 
      controlDigit = "-"; 
     } 
     else 
     { 
      int result = 11 - modular; 
      controlDigit = result.ToString(); 
     } 


     return controlDigit; 
    } 

[ContractClass(typeof(CalculateOrgNumberControlDigitBusinessContract))] 
public interface ICalculateOrgNumberControlDigitBusiness 
{ 
    string getControlDigit(string orgNumberWithoutControlDigit); 
} 


[ContractClassFor(typeof(ICalculateOrgNumberControlDigitBusiness))] 
public abstract class CalculateOrgNumberControlDigitBusinessContract:ICalculateOrgNumberControlDigitBusiness 
{ 
    public string getControlDigit(string orgNumberWithoutControlDigit) 
    { 
     Contract.Requires(orgNumberWithoutControlDigit.Length == 8); 
     int parseResult; 
     Contract.Requires(int.TryParse(orgNumberWithoutControlDigit, out parseResult)); 
     Contract.Ensures(parseResult >= 0); 
     var result = Contract.Result<string>(); 
     Contract.Ensures(result != null && result.Length == 1); 

     return default(string); 
    } 
} 
+0

阅读“纯度”,地址为:http://msdn.microsoft.com/en-us/library/dd264808.aspx –

回答

1

我知道你想达到什么样的,但是我要说的是,经过orgNumberWithoutControlDigit作为一个字符串getControlDigit [原文]是真正的罪魁祸首这里。

即使您可以使您的合同工作 - 调用者也必须将字符串转换为int以满足您的合同。现在,如果调用者已经将该转换转换为int类型,为什么不让它通过int来代替呢?

我是Code Contracts的忠实粉丝,在我的大部分项目中都使用它,并且我已经了解到它不是一颗银色的子弹。所以,如果你必须有一个字符串参数,完全删除合同,并且只需确保你的字符串在使用前是有效的格式。

也许一个OrgNumberValidator帮手会比依靠这个合同更好的选择吗?

编辑:其实,我会建议创建一个OrgNumber类来处理它们。

1

您可以创建一个纯粹的辅助方法,而不是直接调用int.TryParse

[Pure] 
private static bool IsInt(string s) 
{ 
    int n; 
    return int.TryParse(s, out n); 
} 

你可以走得更远,并在try块包裹TryParse,返回false如果任何类型的异常被抛出(刚需在安全的一面)。

但是,我倾向于分享迈克尔的观点,即如果可以的话,避免传递字符串来表示整数,您会做得更好。

+0

是的。另外我在代码合同中发现的一点是,您可以设计'for'合同,但只要您需要这些纯粹的助手来获得合同,那么您就可以做到这一点。 如果你设计了一个类,你不应该将实现添加到该类中去,只是为了获得合同。这只是一个糟糕的合同的症状。你同意吗? –

+0

@MichaelViktorStarberg这是一个有趣的观点。我当然会同意,添加纯助手的需要提出了一种复杂的输入或输出方法,这可能是简化它们的一个机会(并且避免需要帮助者)。 –