罗斯林无法编译code罗斯林、code

2023-09-03 08:26:36 作者:穿草裙的少女

在我迁移从VS2013我的项目VS2015项目不再生成。在下面的LINQ语句出现编译错误:

 静态无效的主要(字串[] args)
{
    十进制A,B;
    IEnumerable的<动态>阵列=新的String [] {10,20,30};
    VAR的结果=(从V阵列
                  其中,decimal.TryParse(V,走出了一条)及和放大器; decimal.TryParse(15,出二)及;&安培; A< = B //这里出错
                  的OrderBy decimal.Parse(v)的
                  选择五).ToArray();
}
 

,编译器会返回一个错误:

  VSCode源码编译

错误CS0165使用未分配的局部变量B

是什么原因导致这个问题?是否有可能通过编译器的设置解决这个问题?

解决方案   

是什么导致这个问题呢?

看起来像一个编译器错误给我。至少,它没有。虽然 decimal.TryParse(V,走出了一条) decimal.TryParse(V,OUT B) EX pressions进行动态评估,我的预计的编译器还是明白的时候达到 A< = B ,无论 A B 被明确赋值。即使在weirdnesses你能想出的动态类型,我希望永远只评估 A< = B 评估两者的后的TryParse 调用。

然而,事实证明,通过运营商和转换棘手的,这是完全可行的有一个前pression A和&放大器; B和;&安培; ç其中计算 A C 而不是 B - 如果你够狡猾。请参阅罗斯林bug报告以尼尔Gafter的巧妙的例子。

制作与作品动态更是难上加难 - 参与当操作数是动态的,是很难来形容,因为为了执行重载,你需要评估的语义操作数找出类型涉及哪些,这可能是反直觉。然而,再次尼尔想出了一个例子展示了所需的编译器错误...这是不是一个错误,这是一个错误的修正的。大量的荣誉给尼尔的证明了。

  

是否有可能通过编译器设置解决这个问题?

没有,但也有替代办法避免的错误。

首先,你可以被动态阻止它 - 如果你知道你将永远只能使用字符串,那么你可以使用的IEnumerable<字符串> 的或的给范围变量 v 从串V A型字符串(即在阵列)。这将是我的preferred选项。

如果您的真正的需要,以保持它的活力,只要给 B 价值入手:

 十进制A,B =0米;
 

这不会做任何伤害 - 我们知道的实际上的你的动态评估不会做任何疯狂的,所以你还是最终分配一个值 B 在使用前,使初始值无关。

此外,似乎加括号工程太:

 其中decimal.TryParse(V,走出了一条)及和放大器; (decimal.TryParse(15,出二)及;&安培; A< = B)
 

这是更改其各个部分重载决议的触发点,并恰好使编译器高兴。

目前的一个的问题仍然保留 - 规范的规则上明确赋值的&功放;&安培; 运营商需要加以澄清,以状态它们只适用于当&功放;&安培; 运营商正在使用中的常规的实施有两个布尔的操作数。我会尽力确保这是固定的下一个ECMA标准。

After I have migrated my project from VS2013 to VS2015 the project no longer builds. A compilation error occurs in the following LINQ statement:

static void Main(string[] args)
{
    decimal a, b;
    IEnumerable<dynamic> array = new string[] { "10", "20", "30" };
    var result = (from v in array
                  where decimal.TryParse(v, out a) && decimal.TryParse("15", out b) && a <= b // Error here
                  orderby decimal.Parse(v)
                  select v).ToArray();
}

The compiler returns an error:

Error CS0165 Use of unassigned local variable 'b'

What causes this issue? Is it possible to fix it through a compiler setting?

解决方案

What does cause this issue?

Looks like a compiler bug to me. At least, it did. Although the decimal.TryParse(v, out a) and decimal.TryParse(v, out b) expressions are evaluated dynamically, I expected the compiler to still understand that by the time it reaches a <= b, both a and b are definitely assigned. Even with the weirdnesses you can come up with in dynamic typing, I'd expect to only ever evaluate a <= b after evaluating both of the TryParse calls.

However, it turns out that through operator and conversion tricky, it's entirely feasible to have an expression A && B && C which evaluates A and C but not B - if you're cunning enough. See the Roslyn bug report for Neal Gafter's ingenious example.

Making that work with dynamic is even harder - the semantics involved when the operands are dynamic are harder to describe, because in order to perform overload resolution, you need to evaluate operands to find out what types are involved, which can be counter-intuitive. However, again Neal has come up with an example which shows that the compiler error is required... this isn't a bug, it's a bug fix. Huge amounts of kudos to Neal for proving it.

Is it possible to fix it through compiler settings?

No, but there are alternatives which avoid the error.

Firstly, you could stop it from being dynamic - if you know that you'll only ever use strings, then you could use IEnumerable<string> or give the range variable v a type of string (i.e. from string v in array). That would be my preferred option.

If you really need to keep it dynamic, just give b a value to start with:

decimal a, b = 0m;

This won't do any harm - we know that actually your dynamic evaluation won't do anything crazy, so you'll still end up assigning a value to b before you use it, making the initial value irrelevant.

Additionally, it seems that adding parentheses works too:

where decimal.TryParse(v, out a) && (decimal.TryParse("15", out b) && a <= b)

That changes the point at which various pieces of overload resolution are triggered, and happens to make the compiler happy.

There is one issue still remaining - the spec's rules on definite assignment with the && operator need to be clarified to state that they only apply when the && operator is being used in its "regular" implementation with two bool operands. I'll try to make sure this is fixed for the next ECMA standard.