我有一个小实用程序类:
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))
为什么会发出这些警告?合同化我的方法的正确(最佳?)方式是什么?
答案 0 :(得分:1)
您的Contract.Ensures()
不能太严格。
大多数框架方法都没有用合同修饰。您无法确定StringBuilder.ToString()
是否会返回空字符串,因为没有关于XmlSerializer.Serialize()
将执行的操作的信息。反序列化相同:没有断言XmlSerializer.Deserialize()
不会返回default(T)
对象的信息。
正如@ TrustMe-ImADoctor在评论中指出的那样,您可能需要在代码中为该断言添加额外的检查,然后静态分析将看到案例被处理且不可能。我想您不需要使用更多检查来污染您的代码,对于这种互操作情况,您可以使用Contract.Assume()
。