如何使用SemanticModel检查变量是否已经过测试?

时间:2014-05-05 20:02:33

标签: c# roslyn

我正在使用Roslyn extension来警告.Value Nullable<T>x.Valueint y; int? x = foo(); y = x != null ? x.Value : 42; if (x > 4) y = x.Value; if (x != null && someExpr) // With && only one branch needs to be a test y = x.Value; if (x == 3 || x == 4) // With || both branches must be a test y = x.Value; if (x == null) return; // Exit method body before access .Value y = x.Value; 次访问。

这提供了以下行为:

Warning: "Nullable 'x' must be checked for null values before accessing 'Value' property"

这个扩展已经有了一定的作用,但是用于测试访问是否安全的代码#34;有点像黑客。我现在只需要遍历语法树looking for if statements

这种方法非常难看,会产生一堆无效的警告。

以下是访问SemanticModel应该是安全的情况的一些示例:

{{1}}

有没有办法使用{{1}}来正确编写此测试?

我想到的一件事就是在语法树上做Abstract interpretation。但这似乎很多工作,我希望不需要一个完整的抽象解释器。

我不太确定如何在Roslyn中实现死代码分析,但它似乎与此有些相关。

2 个答案:

答案 0 :(得分:2)

我根本没玩过Roslyn。但作为ReSharper的用户,我也可以做以下声明:

我的观察是ReSharper只关注相应符号的最近一次使用(类型为Nullable&lt;&gt;)。这是一个迭代证明。如果变量已经(显然)成功使用,则连续使用是安全的。然后由以前的使用情况检查来证明这又是一个安全访问。因此:检查以前的访问权限,以获取另一个先前的访问权限或对null的恢复比较,以查看它是否安全。

if( x != null)
     x.access

示例:

var z = x.Value; // unsafe because it is first and un-tested
var y = x.Value; // safe because it is not first and therefore dependent on first access

答案 1 :(得分:1)

解决这个问题需要流量分析,而Roslyn还没有这样做。