C#IL代码优化:条件运算符(?:)和同一变量的重新赋值

C#IL代码优化:条件运算符(?:)和同一变量的重新赋值,c#,optimization,cil,C#,Optimization,Cil,我在阅读C#7.0变更日志时遇到了一个显示新元组语法的示例 private static (int Max, int Min) Range(IEnumerable<int> numbers) { int min = int.MaxValue; int max = int.MinValue; foreach(var n in numbers) { min = (n < min) ? n : min; max = (n

我在阅读C#7.0变更日志时遇到了一个显示新元组语法的示例

private static (int Max, int Min) Range(IEnumerable<int> numbers)
{
    int min = int.MaxValue;
    int max = int.MinValue;
    foreach(var n in numbers)
    {
        min = (n < min) ? n : min;
        max = (n > max) ? n : max;
    }
    return (max, min);
}
private static(int Max,int Min)范围(IEnumerable number)
{
int min=int.MaxValue;
int max=int.MinValue;
foreach(数值中的变量n)
{
最小值=(n最大值)?n:最大值;
}
返回值(最大值、最小值);
}
我很好奇编译器是否会优化像
min=(n原因
min=min
操作似乎有点无用。我编译了代码(在发布模式下)并在ILDASM中打开它,发现
min=min
赋值仍然存在


对于编译器来说,跳过作业是一个困难的问题吗?或者可能是因为某个多线程问题?

条件运算符的工作方式是,始终为您分配一个值,因为编译器总是希望在“=”之后有一个值。当然,可以编写编译器来检查左侧和右侧是否相同,大多数情况下,重写变量(从右到左)比使用检查来比较两个变量要快,考虑到在大多数情况下,不太可能出现min=min的情况,这只会导致额外的检查,并在99.9%的时间内降低执行速度

程序员的工作是确定何时使用条件运算符或简单的if

int min = int.MaxValue;
int max = int.MinValue;
foreach(var n in numbers)
{

    if(n < min) min = n;
    if(n > max) max = n;
}
int min=int.MaxValue;
int max=int.MinValue;
foreach(数值中的变量n)
{
如果(nmax)max=n;
}

这样,在这种情况下就可以避免min=min赋值。

这是版本一。C#让JIT编译器变得更聪明:@PetSerAl您的示例不完整,因为您使用的是“常量”(这两个变量没有编写)。。。更好是因为它使用了参数。对于字段,它看起来像是重新访问的:这意味着它并没有完全按照“聪明的程序员”进行优化,但是。。我不太擅长机器“ASM”的东西:}对于[
ref
parameters]()也一样(重新访问),我同意,但是如果可以删除赋值,额外的检查将由编译器完成一次,而不是在执行期间,您似乎有点混淆。Wrt./扩展前面的注释:假设没有违反C语言规则,编译器在生成IL时可以推断出与聪明的程序员相同的快捷方式。没有。这意味着规则将被打破,或者这样的优化不值得花时间在这一层实现,因此没有人愿意让Roslyn(或之前的)执行优化。如果优化(与所示的聪明的编码器实现相同)可以在不违反其他约束的情况下完成,则不会有额外的运行时关联。(如果答案是因为这样的优化会违反某些C#[甚至CLR]语言规则,那么这是一个有趣的问题/答案。否则,它通常只是一个“嗯,嘘”。)当然,当给定
x=q时,事物变得“不可替代”?z:x
,其中x指的是不是局部变量的l值(例如,可能是字段、属性)。我同意KekuSemau的观点。这是一个编译时工作。不需要在运行时检查它。也许这种优化可以打破@user2864740的建议。