Mic*_*ito 49 .net c# unreachable-code
我发现了一个案例,我有一些我认为无法访问且未被检测到的代码.编译器和Visual Studio都不会发出警告.
考虑以下代码:
enum Foo { A, B, C }
class Bar { public Foo type; }
static class Program
{
private static void Main()
{
var bar = new Bar { type = Foo.A };
if (bar.type == Foo.B)
{
Console.WriteLine("lol");
}
}
}
Run Code Online (Sandbox Code Playgroud)
显然,程序不会打印出"lol",因为if语句中的条件为false.我不明白为什么没有为无法访问的代码发出警告.我唯一的假设是,如果你在多线程程序中遇到竞争条件,那么这可能是可以达到的.它是否正确?
Avn*_*tan 133
静态分析只能做很多事情,如果能证明代码无法更改,它只会将代码标记为无法访问.在您的代码中,内部发生的事情Bar超出了方法流程的范围,无法进行静态推理.如果Bar构造函数启动一个设置type返回值的线程B怎么办?编译器无法知道它,因为再次,内部Bar结构不是作用于方法的.
如果您的代码正在检查局部变量的值,那么编译器可以知道它是否无法更改.但事实并非如此.
Raw*_*ing 27
在C#规范说,
如果if语句可以访问且布尔表达式没有常量值false,则可以访问if语句的第一个嵌入语句.
并且,关于常数表达式,
常量表达式必须是null文本或与以下类型之一的值:为sbyte,字节,短,USHORT,INT,UINT,长,ULONG,炭,浮点,双精度,小数,布尔,对象,字符串或任何枚举类型.
在常量表达式中只允许以下构造:
- 文字(包括
null文字).- 对类和结构类型的const成员的引用.
- 引用枚举类型的成员.
- 对const参数或局部变量的引用
- 带括号的子表达式,它们本身是常量表达式.
- 如果目标类型是上面列出的类型之一,则转换表达式.选中和未选中的表达式
- 默认值表达式
- 预定义的
+,–,!,和~一元运算符.- 预定义的
+,–,*,/,%,<<,>>,&,|, ,^,&&,||,==,!=,<,>,<=和>=的二进制运算符,提供的每个操作数是上面列出的类型.- 在
?:有条件的经营者.
成员访问表达式不在此列表中,因此布尔表达式不是常量.因此if块的主体是可达的.
因为在编译时不能做出这样的保证.考虑这个替代Bar类
class Bar
{
Random random = new Random();
Array Foos = Enum.GetValues(typeof(Foo));
private Foo _type;
public Foo type
{
get { return _type; }
set
{
_type = (Foo)Foos.GetValue(random.Next(3));
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,"可达"是在功能级别定义的.即使在安全的情况下,也不允许到达正在测试的功能之外.
| 归档时间: |
|
| 查看次数: |
9483 次 |
| 最近记录: |