为什么这个(null ||!TryParse)条件导致“使用未分配的局部variables”?

以下代码导致使用未分配的局部variables“numberOfGroups”

int numberOfGroups; if(options.NumberOfGroups == null || !int.TryParse(options.NumberOfGroups, out numberOfGroups)) { numberOfGroups = 10; } 

但是,这段代码工作正常(虽然, ReSharper说= 10是多余的):

 int numberOfGroups = 10; if(options.NumberOfGroups == null || !int.TryParse(options.NumberOfGroups, out numberOfGroups)) { numberOfGroups = 10; } 

我错过了什么,或者编译器不喜欢我的||

我已经缩小到dynamic导致的问题( options是我上面的代码中的一个dynamicvariables)。 问题仍然存在, 为什么我不能这样做

这段代码不能编译:

 internal class Program { #region Static Methods private static void Main(string[] args) { dynamic myString = args[0]; int myInt; if(myString == null || !int.TryParse(myString, out myInt)) { myInt = 10; } Console.WriteLine(myInt); } #endregion } 

但是,这个代码确实

 internal class Program { #region Static Methods private static void Main(string[] args) { var myString = args[0]; // var would be string int myInt; if(myString == null || !int.TryParse(myString, out myInt)) { myInt = 10; } Console.WriteLine(myInt); } #endregion } 

我没有意识到dynamic将是一个因素。

我很确定这是一个编译器错误。 很好找!

编辑:这不是一个错误,正如Quartermeister所示; dynamic可能会实现一个奇怪的true运算符,这可能会导致永远不会被初始化。

这是一个最小的repro:

 class Program { static bool M(out int x) { x = 123; return true; } static int N(dynamic d) { int y; if(d || M(out y)) y = 10; return y; } } 

我没有理由认为这是非法的。 如果你用boolreplacedynamic,它编译就好了。

实际上我明天和C#团队会面 我会提到他们。 道歉的错误!

如果dynamicexpression式的值是一个重载的true操作符的types,则可以将该variables取消分配。

|| 运算符将调用true运算符来决定是否评估右侧,然后if语句将调用true运算符来决定是否评估其正文。 对于一个正常的bool ,这些将总是返回相同的结果,所以只有一个将被评估,但对于用户定义的运算符没有这样的保证!

以Eric Lippert的复制品为基础,这里是一个简短而完整的程序,它展示了一个既不会执行path也不会有variables初始值的情况:

 using System; class Program { static bool M(out int x) { x = 123; return true; } static int N(dynamic d) { int y = 3; if (d || M(out y)) y = 10; return y; } static void Main(string[] args) { var result = N(new EvilBool()); // Prints 3! Console.WriteLine(result); } } class EvilBool { private bool value; public static bool operator true(EvilBool b) { // Return true the first time this is called // and false the second time b.value = !b.value; return b.value; } public static bool operator false(EvilBool b) { throw new NotImplementedException(); } } 

来自MSDN (强调我的):

dynamictypes使得它发生的操作可以绕过编译时types检查 。 相反,这些操作在运行时解决 。 dynamictypes简化了对诸如Office自动化API之类的COM API的访问,以及诸如IronPython库之类的dynamicAPI以及对HTML文档对象模型(DOM)的访问。

在大多数情况下,typesdynamic行为就像types对象。 但是, 包含dynamictypesexpression式的操作不会被编译器parsing或types检查。

由于编译器不检查或parsing包含dynamictypesexpression式的任何操作,因此不能确保通过使用TryParse()来分配variables。