C# 由于潜在的副作用而导致错误的代码契约
我对代码契约相当陌生,所以我可能在这里做了一些愚蠢的事情:) 我发现了错误 检测到表达式语句在中评估了潜在的副作用 方法“##”的合同。(你的意思是把这个表达变成 需要、确保或不变调用?) 我有以下合同C# 由于潜在的副作用而导致错误的代码契约,c#,code-contracts,C#,Code Contracts,我对代码契约相当陌生,所以我可能在这里做了一些愚蠢的事情:) 我发现了错误 检测到表达式语句在中评估了潜在的副作用 方法“##”的合同。(你的意思是把这个表达变成 需要、确保或不变调用?) 我有以下合同 Contract.Requires<ArgumentNullException>(obj != null); Contract.Requires<ArgumentNullException>(obj.Id != null); Contract.Requires(obj!
Contract.Requires<ArgumentNullException>(obj != null);
Contract.Requires<ArgumentNullException>(obj.Id != null);
Contract.Requires(obj!=null);
Contract.Requires(obj.Id!=null);
第二个合同obj.Id!=null
(Id
是Guid
)
现在可以将Id
设置为null
,这在方法中是不允许的。但是代码契约会引发上述编译错误。它自己的方法实际上不返回任何东西,因此也不需要任何保证
我已经删除了合同,因此我可以编译并放置一个标准的
if
检查。但是是什么导致了这种情况?您需要将Id属性本身标记为
这将告诉代码分析器它没有副作用
代码契约不喜欢调用有副作用的方法;根据是否启用了代码契约检查,代码的行为会有所不同,这是一件坏事
例如:
public Guid Id
{
[Pure]
get
{
return _id;
}
}
还有一点:如果是Guid,
Id
怎么可能为空?Guid是结构,因此不能为空。它是否可能是一个可为空的Guid(即Guid?
)?这里的确认pure意味着不能像SetId方法或其他东西那样间接更改Id?当您说[pure]
时,您告诉代码分析您承诺(通过getter)访问属性不会更改拥有该属性的对象的可观察状态。然而,你可以违背诺言——但不要!还要注意,setter将不是[纯](当然)。但这与任何其他调用(来自此代码或任何其他代码)是否会更改Id
无关。是的,这是有意义的。但是你遇到了实际的问题,我忘了将guid标记为可空类型:SYes我将从现在开始我在很多地方不使用它自动添加guid属性会很好怎么可以为空?这是一个结构!我怀疑你的Id属性是字符串