CodeContract警告

时间:2012-06-15 09:05:39

标签: c# code-contracts

我有一个小实用程序类:

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);
        }
    }
}

这两种方法按预期工作。

但是,代码合同静态检查器会抛出两个警告:

  

警告30 CodeContracts:确保未经证实:   !string.IsNullOrEmpty(Contract.Result())

     

警告28 CodeContracts:确保未经证实:   !object.Equals(Contract.Result(),default(T))

为什么会发出这些警告?合同化我的方法的正确(最佳?)方式是什么?

1 个答案:

答案 0 :(得分:1)

您的Contract.Ensures()不能太严格。

大多数框架方法都没有用合同修饰。您无法确定StringBuilder.ToString()是否会返回空字符串,因为没有关于XmlSerializer.Serialize()将执行的操作的信息。反序列化相同:没有断言XmlSerializer.Deserialize()不会返回default(T)对象的信息。

正如@ TrustMe-ImADoctor在评论中指出的那样,您可能需要在代码中为该断言添加额外的检查,然后静态分析将看到案例被处理且不可能。我想您不需要使用更多检查来污染您的代码,对于这种互操作情况,您可以使用Contract.Assume()