2

私は小さなユーティリティクラスを持っています:

public static class SerializationUtilities
{
    public static string ToXml<T>(T @object)
    {
        Contract.Requires<ArgumentNullException>(@object != null);
        Contract.Requires<ArgumentException>(typeof(T).IsSerializable);
        Contract.Ensures(!string.IsNullOrEmpty(Contract.Result<string>()));

        var xs = new XmlSerializer(typeof(T));
        var result = new StringBuilder();

        using (var sw = new StringWriter(result))
        {
            xs.Serialize(sw, @object);
        }
        return result.ToString();
    }

    public static T FromXml<T>(string xml)
    {
        Contract.Requires<ArgumentNullException>(!string.IsNullOrEmpty(xml));
        Contract.Ensures(!object.Equals(Contract.Result<T>(), default(T)));

        var xs = new XmlSerializer(typeof(T));
        using (var sr = new StringReader(xml))
        {
            return (T)xs.Deserialize(sr);
        }
    }
}

2つの方法は期待どおりに機能しています。

ただし、コードコントラクト静的チェッカーは2つの警告をスローしています。

警告30CodeContracts:証明されていないことを保証します:!string.IsNullOrEmpty(Contract.Result())

警告28CodeContracts:証明されていないことを保証します:!object.Equals(Contract.Result()、default(T))

なぜこれらの警告が発せられるのですか?私の方法を契約するための正しい(最良の)方法は何ですか?

4

1 に答える 1

1

あなたContract.Ensures()はそれほど厳格にすることはできません。

フレームワークメソッドのほとんどは、コントラクトで装飾されていません。StringBuilder.ToString()何をするかについての情報がないので、それが空の文字列を返さないことを確信することはできませXmlSerializer.Serialize()ん。デシリアライズについても同じです。オブジェクトXmlSerializer.Deserialize()を返さないことを表明する情報はありません。default(T)

コメントで@TrustMe-ImADoctorが指摘しているように、そのアサーションのコードにチェックを追加する必要がある場合があります。静的分析では、ケースが処理され、不可能であることがわかります。より多くのチェックでコードを汚染する必要はないと思います。この相互運用の場合は、を使用するだけContract.Assume()です。

于 2012-06-15T09:42:26.663 に答える