如何在代码合同中使用TryParse而不会收到警告

时间:2013-01-02 09:47:17

标签: c# code-contracts

使用代码合同时,我收到警告:

  

检测到对方法的调用   'System.Int32.TryParse(System.String,System.Int32 @)'没有[Pure] in   方法合同

在接口上定义一个接口和代码契约的类,如下面的代码所示。问题是如何检查字符串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);
    }
}

2 个答案:

答案 0 :(得分:1)

我理解你想要实现的目标,但我会说将orgNumberWithoutControlDigit作为字符串传递给getControlDigit [sic]是真正的罪魁祸首。

即使您可以使合同生效 - 调用者也必须将字符串转换为int以满足您的合同。现在,如果调用者已经将转换转换为int,那么为什么不让它传递那个int呢?

我是Code Contracts的忠实粉丝,并且在我的大部分项目中都使用它,而且我了解到它不是一个灵丹妙药。因此,如果您必须拥有字符串参数,请完全删除合同,并在使用前确保您的字符串采用有效格式。

也许一个OrgNumberValidator助手比依赖合同更好吗?

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

答案 1 :(得分:1)

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

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

您可以更进一步将TryParse包装在try块中,如果抛出任何类型的异常,则返回false(只是为了安全起见)。

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