英文:
Odd string interpolation Null Reference Exception when debugging
问题
更新到更新(因为这只是在怪异的世界中迷失了)
好的,我现在完全迷失了。我注意到在我的更新中,第7行的{b}
后面缺少句点。所以,为了保证准确性,我添加了它。
!!!现在第7行也会在您进入时失败!!!
这到底是怎么回事???
所以,现在的Program.cs
带来了更疯狂的结果...
try
{
var a = "a";
var b = "b";
var r1 = "r";
var r1x = $"r2x1={a}.{b}.{r1}"; // < Line 6 - F10 here will give you an exception
var r1y = $"r2x1={a}.{b}" + r1; // < Line 7 - F10 here will execute just fine!
var r1z = $"r2x1={a}.{b}." + r1; // < Line 8 - F10 here will give you the exception!!!
var r1a = $"r2x1={a}.{b}{r1}"; // < Line 9 - F10 here will give you an exception
Console.WriteLine(r1x);
}
catch (NullReferenceException e)
{
Console.WriteLine(e);
}
更新
我进一步研究了这个问题,发现问题似乎与字符串插值直接相关。在更新后的Program.cs
中,如果在第6行(var r1x = ...
)上设置断点,如果您使用F10
执行它,会创建一个异常,但如果使用F5
执行它,它将运行得很愉快。然而,同时在第7行(var r1y = ...
)上设置断点也将允许您愉快地执行F10
!
try
{
var a = "a";
var b = "b";
var r1 = "r";
var r1x = $"r2x1={a}.{b}.{r1}"; // < Line 6 - F10 here will give you an exception
var r1y = $"r2x1={a}.{b}" + r1; // < Line 7 - F10 here will execute just fine!
Console.WriteLine(r1x);
}
catch (NullReferenceException e)
{
Console.WriteLine(e);
}
原始问题如下
Program.cs:
try
{
var a = "a";
var b = "b";
var r1 = "r";
var r2 = "r";
r1 = $"r1={a}.{b}.{r1}";
r2 = $"r2={a}.{b}.{r2}";
Console.WriteLine(r1);
Console.WriteLine(r2);
}
catch (NullReferenceException e)
{
Console.WriteLine(e.StackTrace);
}
这段愚蠢的代码将正常运行 - 如果您不使用调试器逐行步进。
然而,在第8行(r2 = ...
)上设置断点会导致您进入catch
并出现NullReferenceException
,并且
System.NullReferenceException: Object reference not set to an instance of an object.
at System.Buffer.Memmove(Byte& dest, Byte& src, UIntPtr len)
at System.Runtime.CompilerServices.DefaultInterpolatedStringHandler.AppendStringDirect(String value)
at Program.<Main>$(String[] args) in /Users/rambler/tmp/Four Weeks/why/ConsoleApp1/Program.cs:line 8
同样,在第7行上设置断点也会产生相同的异常。如果没有在任何一行上设置断点,那么执行将没有异常。
我已经尝试了几种r1 = ...
和r2 = ...
的变体,其中一些使用了与r1
(或r2
)相关的字符串插值,结果很难确定。
到目前为止,我在我的Mac上使用Rider和Visual Studio Code都遇到了这个问题。稍后我会在Windows上测试,看看是否也可以重现这个问题。
这个问题是在我正在编写的一个规模更大的应用程序中浮出水面的 - 我终于能够将它限制在这个问题上了。
.net 7.0.203
英文:
UPDATE TO THE UPDATE (Because this is just getting lost in bizarro world)
OK, I'm now totally blow away. I noticed in my update, I was missing the period after {b}
on line 7. So, being a sticker for accuracy, I added it in.
!!!Now Line 7 also fails when you step into it!!!
What in the world????
So, now Program.cs
with more crazy results...
try
{
var a = "a";
var b = "b";
var r1 = "r";
var r1x = $"r2x1={a}.{b}.{r1}"; // < Line 6 - F10 here will give you an exception
var r1y = $"r2x1={a}.{b}" + r1; // < Line 7 - F10 here will execute just fine!
var r1z = $"r2x1={a}.{b}." + r1; // < Line 8 - F10 here will give you the exception!!!
var r1a = $"r2x1={a}.{b}{r1}"; // < Line 9 - F10 here will give you an exception
Console.WriteLine(r1x);
}
catch (NullReferenceException e)
{
Console.WriteLine(e);
}
Update
I messed around some more with this, and the issue seems to be directly related to the string interpolation. In the updated Program.cs
directly below, adding a breakpoint on Line 6 (var r1x = ...
) will create an exception if you F10
over it, will happily run if you F5
it. However also having a breakpoint on line 7 (var r1y = ...
) will happily allow you to F10
past it!
try
{
var a = "a";
var b = "b";
var r1 = "r";
var r1x = $"r2x1={a}.{b}.{r1}"; // < Line 6 - F10 here will give you an exception
var r1y = $"r2x1={a}.{b}" + r1; // < Line 7 - F10 here will execute just fine!
Console.WriteLine(r1x);
}
catch (NullReferenceException e)
{
Console.WriteLine(e);
}
Original question below
Program.cs:
try
{
var a = "a";
var b = "b";
var r1 = "r";
var r2 = "r";
r1 = $"r1={a}.{b}.{r1}";
r2 = $"r2={a}.{b}.{r2}";
Console.WriteLine(r1);
Console.WriteLine(r2);
}
catch (NullReferenceException e)
{
Console.WriteLine(e.StackTrace);
}
This silly bit of code will run just fine - if you're not doing line by line step-through with the debugger.
However placing a breakpoint on line 8 (r2 = ...
) will drop you into the catch
with a NullReferenceException
and
System.NullReferenceException: Object reference not set to an instance of an object.
at System.Buffer.Memmove(Byte& dest, Byte& src, UIntPtr len)
at System.Runtime.CompilerServices.DefaultInterpolatedStringHandler.AppendStringDirect(String value)
at Program.<Main>$(String[] args) in /Users/rambler/tmp/Four Weeks/why/ConsoleApp1/Program.cs:line 8
Equally doing a breakpoint and line 7 will yield the same exception. Not having a breakpoint on either line will however result in an exception free execution.
I've tried several variations of the r1 = ...
and r2 = ...
, some which use string interpolation with r1
(or r2
respectively) and I get hard to pin down results.
All times though the code runs if I don't try to debug that particular line.
So far this has been on my Mac using both Rider and Visual Studio Code. Going to fire up Windows later on to see if I can replicate it there as well.
This issue came to light on a much much bigger app I'm writing - and I've been finally able to limit it down to just this.
.net 7.0.203
答案1
得分: 0
计算属性/值对于调试器来说是一个挑战,因为调试器要求一个变量在不应该被访问的时间/状态中计算并显示一个值,或者它在复杂操作的中间,这是调试器捕获的失败。
调试器与插值存在一种竞争条件,因为代码在应用程序操作中运行得非常好;存在某个点,其中一个空引用被写入或覆盖,并由调试器传播。
因此,可以说调试器存在问题,但编码是为了实际场景而不是调试场景。
我经常在具有计算属性的类中看到这种情况。在调试器中,它显示一个仅在调试期间看到的异常
属性。
英文:
Computed properties/values are a challenge for a debugger, for the debugger is asking a variable to compute and show a value in a time/state that the value is not meant to be accessed, or it's in the middle of a complex operation and that is a failure caught by the debugger.
The debugger is in a type of race condition with the interpolation since the code works just fine in an application operation; there is some point where a null reference is being written or overwritten and being propagated by the debugger.
Hence one could say there is an issue with the debugger, but one codes for a real-world scenario and not a debugging scenario.
I see this all the time with classes that have properties which compute something. In the debugger it shows an exception
for a property that is only seen during debugging.
答案2
得分: 0
这已得到他人确认:
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论