3

Code Contracts を使用すると、次の警告が表示されます。

メソッドのコントラクトで [Pure] なしのメソッド 'System.Int32.TryParse(System.String,System.Int32@)' への呼び出しが検出されました

以下のコードのように、インターフェイスで定義されたインターフェイスとコード コントラクトを持つクラスを持つ。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);
    }
}
4

2 に答える 2

1

int.TryParse直接呼び出す代わりに、純粋なヘルパーメソッドを作成できます。

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

TryParseさらに進んで、をブロックでラップし、何らかのタイプの例外がスローされた場合tryに返すことができます(念のため)。false

ただし、可能であれば、整数を表す文字列を渡さない方がよいというMichaelの意見を共有する傾向があります。

于 2013-01-02T11:13:08.743 に答える
1

あなたが達成したいことは理解していますが、orgNumberWithoutControlDigit を文字列として getControlDigit [sic] に渡すことが本当の原因だと思います。

契約を機能させることができたとしても、契約を満たすために、呼び出し元は文字列を int に変換する必要もあります。呼び出し元が既にその int への変換を行っている場合は、代わりにその int を渡してみましょう。

私は Code Contracts の大ファンであり、ほとんどのプロジェクトでこれを使用していますが、それが特効薬ではないことを学びました。したがって、文字列パラメーターが必要な場合は、コントラクトを完全に削除し、使用する前に文字列が有効な形式であることを確認してください。

おそらく、OrgNumberValidator ヘルパーは、これを契約に頼るよりも良い選択でしょうか?

編集:実際には、それらを処理するために OrgNumber クラスを作成することをお勧めします。

于 2013-01-02T10:31:41.460 に答える