罗斯林无法编译code [英] Roslyn failed to compile code

查看:162
本文介绍了罗斯林无法编译code的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我迁移从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();
}
 

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

  

错误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.

这篇关于罗斯林无法编译code的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆