gpt4 book ai didi

c# - "?"类型修饰符优先级 vs 逻辑与运算符 (&) vs address-of operator (&)

转载 作者:可可西里 更新时间:2023-11-01 08:46:13 27 4
gpt4 key购买 nike

更新:似乎我不太清楚我到底在问什么(随着时间的推移,我也有点迷失了问题),所以这是一个tl;dr版本:

var test1 = a is byte & b;    // compiles
var test2 = a is byte? & b; // does not compile
var test3 = a is byte? && b; // compiles

这意味着 - 据我所知 - ? 类型修饰符的优先级(因为它不是运算符,这可能不是最好的词)低于 & 运算符,但高于 && 运算符。是这样吗?这在标准中的何处描述?


原始问题:

在试图从 Jon Skeet 的优秀博文中找出第二个谜题的答案时,A Tale of two puzzles ,我遇到了一个问题:

unsafe private void Test<T>(T a, bool b) 
{
var test1 = a is byte? & b; // does not compile
var test2 = a is byte? && b; // compiles
var test3 = a is byte ? & b : & b; // compiles
}

这里我使用了一个 unsafe 上下文,因为我的实际目标需要它(例如:第三行),但它不是重现我提出的问题所必需的。 (但是它可能会产生影响,因为它引入了寻址操作符作为 & 符号的替代。)

第一行没有编译(其他行),它给出了以下错误信息:

Syntax error, ':' expected

这意味着在那种情况下,编译器将该行视为

var test1 = (a is byte) ? &b [: missing part that it complains about];

虽然在第二行中它认为它是:

var test2 = (a is byte?) && (b);

我检查了运算符优先级 ( here ),顺序(从高到低)如下:&, &&, ?: ,所以仅凭这一点并不能解释为什么第一行不编译而第二个编译(或者至少对我来说不是 - 也许这是我错的地方......)编辑:我明白为什么第二个编译,所以请不要专注于此在你的回答中。

我的下一个直觉是,? 类型修饰符的优先级(如果有的话)不知何故介于这两个(或实际上是三个)运算符之间 ( &&&)。可以这样吗?如果不能,有人可以解释我正在经历的确切行为吗? ? 类型修饰符的求值顺序是否在标准的某处明确描述?

编辑: 我也知道有一个一元地址运算符(实际上这是我试图用于解决方案的技巧......),它在这里发挥作用,但是我的问题还是一样。

在相同的 unsafe 上下文中那些愉快地编译:

var test1 = true & b;
var test2 = true && b;
// or
var test1 = a is byte & b;
var test2 = a is byte && b;

所以我认为它一定与 ? 修饰符/运算符有关,而不仅仅是与优先的地址运算符有关(否则两行 test1 不会编译)。

P.S.:我知道我可以在我的代码中添加括号,所以它会编译,但我想避免这种情况:

var test = (a is byte?) & b;   // compiles

更新:我对 Roslyn 进行了一些试验,我认为为各种语句附加 AST 可能是个好主意:

var test1 = a is byte & b;

AST for test1 line

var test2 = a is byte? & b;

AST for test2 line

var test3 = a is byte? && b;

AST for test3 line


我想强调的是,我不是在链接文章中寻找原始问题的解决方案(当然我正在寻找一个,但我请你不要在这里给出答案,因为我想自己找出答案。)另外,如果我在寻找解决方案的过程中完全走错了路,请不要发表评论,我提到这个难题只是为了为我的特定问题提供一些背景信息,并为编写这样的代码提供足够好的借口。

最佳答案

这里的线索是 unsafe 关键字。实际上有两种不同的 & 运算符 - 你习惯的按位与 & 运算符,还有地址 & 运算符,它不仅具有更高的优先级,而且是 evaluated right-to-left ,就像所有一元运算符一样。

这意味着 &b 首先被评估,并产生一个指针值。正如编译器所提示的那样,该语句的其余部分是不可解析的。它要么是 (a is byte?) (address),要么(当编译器试图解析它时)(a is byte)? (地址) 并且缺少 :

将 & 替换为 +- 时,我遇到了相同的编译错误,这两个符号都可以是一元或二元运算符。

第二条语句编译良好的原因是没有一元的、从右到左的高优先级 && 运算符。

关于c# - "?"类型修饰符优先级 vs 逻辑与运算符 (&) vs address-of operator (&),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24305290/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com