如何构造非true/false的bool值触发C# switch默认分支?
如何构造非true非false的bool值让switch走到default分支
嘿,这个问题真的很有意思!你说的没错,确实可以通过StructLayout这类内存操作的黑科技,构造出一个不符合CLR规范的bool值,让你的switch代码走到default分支。
原理说明
在CLR的规范里,bool类型本质是1字节的数值,合法值只有0(对应false)和1(对应true)。但如果我们绕开C#的类型安全检查,直接修改bool对应的内存字节为其他值(比如2),就会得到一个既不是true也不是false的"非法"bool值。而switch语句对bool的匹配是严格按值判断的:case true只匹配值为1的bool,case false只匹配值为0的bool,其他值就会触发default分支。
具体实现代码
用StructLayout的显式内存布局来实现内存重叠,直接修改bool对应的字节:
using System; using System.Runtime.InteropServices; class WeirdBoolDemo { // 定义显式布局的结构体,让bool和byte共享同一块内存 [StructLayout(LayoutKind.Explicit)] private struct BoolByteUnion { [FieldOffset(0)] public bool BooleanValue; [FieldOffset(0)] public byte ByteValue; } static bool GetMyWeirdBool() { var union = new BoolByteUnion(); // 给字节赋值一个非0非1的值,比如2 union.ByteValue = 2; // 返回被篡改后的bool return union.BooleanValue; } static void Main() { bool b = GetMyWeirdBool(); switch (b) { case true: Console.WriteLine("true"); break; case false: Console.WriteLine("false"); break; default: Console.WriteLine("neither o_0"); break; } } }
运行这段代码,你会看到输出neither o_0,完美触发了default分支。
额外说明
- 你也可以用
unsafe代码直接操作内存指针来实现,效果是一样的:unsafe static bool GetMyWeirdBool() { bool b = false; byte* ptr = (byte*)&b; *ptr = 3; // 随便一个非0非1的值都行 return b; } - 这种做法是严重违反CLR类型安全规范的黑科技,只能用来做演示或理解底层原理,绝对不能在生产代码中使用!CLR在很多场景下会假设bool的值只有0或1,比如
if(b)会把任何非0的bool值视为true,但switch的匹配逻辑是严格按值对比,所以才会出现这种"矛盾"的行为。
内容的提问来源于stack exchange,提问作者Alex Zhukovskiy
相关产品推荐
相关产品推荐

