.Net 4.5.2 中 Debug.Assert(condition, interpolatedStringMessage) 的评估顺序
Order of evaluation for Debug.Assert(condition, interpolatedStringMessage) in .Net 4.5.2
我在这里偶然发现了 C#/.Net 4.5.2 中的一个奇怪问题……
我在 Debug.Assert()
中进行了 !ContainsKey()
检查,其中包含包含值的内插字符串,如果找到,就像这样
var dict = new Dictionary<string, string>();
string invalidKey = "invalidKey";
try
{
Debug.Assert((!dict.ContainsKey(invalidKey)), $"{nameof(dict)} contains the key {dict[invalidKey]}!");
}
catch (KeyNotFoundException)
{
Console.WriteLine("AssertionString was interpolated before the check was performed!");
}
(只是在我的第一个版本中没有 try-catch 块)
我本来希望永远不会 运行 进入 catch
那里,例如,情况也是如此。检查 .NETFiddle 中的代码(参见 https://dotnetfiddle.net/RyQooW ),但是,在 Visual Studio、运行 .Net 4.5.2 下的代码中,我得到以下信息:
interpolated string evaluated before assertion condition
绝对是字符串插值(ContainsKey
没有问题),因为当我从消息中删除插值时,不会抛出异常。
评价顺序不保证?我认为如果断言为真,则不会对字符串进行插值。
或者这只是这个版本的 .Net 运行时中的一个错误(也许是一种优化,可以尽早插入断言字符串以使它们成为静态的或其他什么?)
感谢任何意见,干杯!
好吧,对于所有遇到这个问题的人来说:
它 不是 一个错误,显然,但实际上只是 Debug.Assert
作为一个常规方法(不是一些特殊的 built-in 帮助程序等,请参阅也 Microsoft's reference source),因此任何字符串参数 必须 在 进入方法之前被插入 (因为所讨论的对象可能不是在调用范围外可用)。
但是由于条件和消息都是方法参数,并且条件的评估发生在 inside 方法(并且 not 方法调用作为result of the evaluation),上面的KeyNotFoundException
当然是在进入方法和检查条件之前抛出的。
唯一使 Debug.Assert
有点特别的是它具有 [System.Diagnostics.Conditional("DEBUG")]
属性,因此在 non-Debug 构建中被剥离。
所以这实际上是完全可以理解和正确的行为(在 any dot net 版本中),尽管它是一种陷阱。
我在这里偶然发现了 C#/.Net 4.5.2 中的一个奇怪问题……
我在 Debug.Assert()
中进行了 !ContainsKey()
检查,其中包含包含值的内插字符串,如果找到,就像这样
var dict = new Dictionary<string, string>();
string invalidKey = "invalidKey";
try
{
Debug.Assert((!dict.ContainsKey(invalidKey)), $"{nameof(dict)} contains the key {dict[invalidKey]}!");
}
catch (KeyNotFoundException)
{
Console.WriteLine("AssertionString was interpolated before the check was performed!");
}
(只是在我的第一个版本中没有 try-catch 块)
我本来希望永远不会 运行 进入 catch
那里,例如,情况也是如此。检查 .NETFiddle 中的代码(参见 https://dotnetfiddle.net/RyQooW ),但是,在 Visual Studio、运行 .Net 4.5.2 下的代码中,我得到以下信息:
interpolated string evaluated before assertion condition
绝对是字符串插值(ContainsKey
没有问题),因为当我从消息中删除插值时,不会抛出异常。
评价顺序不保证?我认为如果断言为真,则不会对字符串进行插值。
或者这只是这个版本的 .Net 运行时中的一个错误(也许是一种优化,可以尽早插入断言字符串以使它们成为静态的或其他什么?)
感谢任何意见,干杯!
好吧,对于所有遇到这个问题的人来说:
它 不是 一个错误,显然,但实际上只是 Debug.Assert
作为一个常规方法(不是一些特殊的 built-in 帮助程序等,请参阅也 Microsoft's reference source),因此任何字符串参数 必须 在 进入方法之前被插入 (因为所讨论的对象可能不是在调用范围外可用)。
但是由于条件和消息都是方法参数,并且条件的评估发生在 inside 方法(并且 not 方法调用作为result of the evaluation),上面的KeyNotFoundException
当然是在进入方法和检查条件之前抛出的。
唯一使 Debug.Assert
有点特别的是它具有 [System.Diagnostics.Conditional("DEBUG")]
属性,因此在 non-Debug 构建中被剥离。
所以这实际上是完全可以理解和正确的行为(在 any dot net 版本中),尽管它是一种陷阱。