为什么 Code Contracts 建议我要求参数为空?
Why is Code Contracts suggesting that I require a parameter to be null?
查看下面的代码示例,Microsoft Code Contracts 警告:
CodeContracts: Missing precondition in an extremely visible method.
Consider adding Contract.Requires(science == null); for parameter
validation
我是不是漏掉了什么?为什么CC会建议我要求参数为null,这与这里应该做的完全相反?
我正在使用 VS2015、.NET 4.6。
using System;
using System.Diagnostics.Contracts;
public sealed class Weird
{
public Weird(object science)
{
if (null == science)
{
throw new ArgumentNullException();
}
Contract.EndContractBlock();
this.Science = science;
}
private object Science { get; }
[ContractInvariantMethod]
private void ObjectInvariant()
{
Contract.Invariant(null != this.Science);
}
}
尽量不要使用反向比较。在 C# 中,无需编写:
if (null == science)
而不是
if (science == null)
你的代码会变得更清晰,我想错误的合约建议也会消失。
另外,如果你犯了一个错误,只在 if
块中写了一个赋值 (=
),编译器会警告你。
为了使您的代码更加清晰,您可以尝试使用一些 AOP 工具,例如 PostSharp,并将您的合同指定为接口中的 属性 属性,您的 class 将实现该属性。因此合同逻辑不会与业务逻辑交织。
我发现当我用字段支持的 属性 替换自动 属性 时警告消失了。将以下代码与我在原始问题中发布的代码进行比较:
using System;
using System.Diagnostics.Contracts;
public sealed class Weird
{
public Weird(object science)
{
if (science == null)
{
throw new ArgumentNullException();
}
Contract.EndContractBlock();
this.science = science;
}
private readonly object science;
private object Science
{
get
{
return this.science;
}
}
[ContractInvariantMethod]
private void ObjectInvariant()
{
Contract.Invariant(null != this.Science);
}
}
我不喜欢这个,因为我不一定要使用现场支持 属性 只是为了满足代码合同的目的。但是,哦,好吧,我想。
我仍然愿意接受允许我在使用汽车属性时满足我的合同的答案。
这不是比您的解决方法更好的答案,但我通过简单地更改 "work" 得到了它:
private object Science { get; }
至:
private object Science { get; set; }
与您的解决方法基本相同,但不提供您自己的支持字段。我猜 Code Contracts 不太理解新语法。
根据变通方法,CC 似乎不明白只读自动 属性 在构造函数中是可写的。提供的两种解决方法都删除了写入只读 属性 的操作。也许 CC 试图通过将执行发送到唯一可用的其他分支 ( null == science
).
来避免执行它认为有错误的语句 ( this.Science = science;
)。
早期版本的 C# 不允许写入只读自动 属性。我猜代码合同系统没有收到备忘录!
查看下面的代码示例,Microsoft Code Contracts 警告:
CodeContracts: Missing precondition in an extremely visible method. Consider adding Contract.Requires(science == null); for parameter validation
我是不是漏掉了什么?为什么CC会建议我要求参数为null,这与这里应该做的完全相反?
我正在使用 VS2015、.NET 4.6。
using System;
using System.Diagnostics.Contracts;
public sealed class Weird
{
public Weird(object science)
{
if (null == science)
{
throw new ArgumentNullException();
}
Contract.EndContractBlock();
this.Science = science;
}
private object Science { get; }
[ContractInvariantMethod]
private void ObjectInvariant()
{
Contract.Invariant(null != this.Science);
}
}
尽量不要使用反向比较。在 C# 中,无需编写:
if (null == science)
而不是
if (science == null)
你的代码会变得更清晰,我想错误的合约建议也会消失。
另外,如果你犯了一个错误,只在 if
块中写了一个赋值 (=
),编译器会警告你。
为了使您的代码更加清晰,您可以尝试使用一些 AOP 工具,例如 PostSharp,并将您的合同指定为接口中的 属性 属性,您的 class 将实现该属性。因此合同逻辑不会与业务逻辑交织。
我发现当我用字段支持的 属性 替换自动 属性 时警告消失了。将以下代码与我在原始问题中发布的代码进行比较:
using System;
using System.Diagnostics.Contracts;
public sealed class Weird
{
public Weird(object science)
{
if (science == null)
{
throw new ArgumentNullException();
}
Contract.EndContractBlock();
this.science = science;
}
private readonly object science;
private object Science
{
get
{
return this.science;
}
}
[ContractInvariantMethod]
private void ObjectInvariant()
{
Contract.Invariant(null != this.Science);
}
}
我不喜欢这个,因为我不一定要使用现场支持 属性 只是为了满足代码合同的目的。但是,哦,好吧,我想。
我仍然愿意接受允许我在使用汽车属性时满足我的合同的答案。
这不是比您的解决方法更好的答案,但我通过简单地更改 "work" 得到了它:
private object Science { get; }
至:
private object Science { get; set; }
与您的解决方法基本相同,但不提供您自己的支持字段。我猜 Code Contracts 不太理解新语法。
根据变通方法,CC 似乎不明白只读自动 属性 在构造函数中是可写的。提供的两种解决方法都删除了写入只读 属性 的操作。也许 CC 试图通过将执行发送到唯一可用的其他分支 ( null == science
).
this.Science = science;
)。
早期版本的 C# 不允许写入只读自动 属性。我猜代码合同系统没有收到备忘录!