NullReferenceException: CS$<>8__locals0 was null

.Net技术 码拜 3个月前 (08-08) 155次浏览 0个评论

When i use a variable in a linq expression inside a if statement that evaluates to false, and in debug mode drags execution pointer inside the If statement, i get a Null Ref exeption.

在 linq 表达式中使用int变量的时候,由于希望执行目标代码,所以拖动了执行断点,进入了if语句,但是赋值一直抛出异常: System.NullReferenceException: 未将对象引用设置到对象的实例。CS$<>8__locals0 是 null

Here is the code

using System.Collections.Generic;
using System.Linq;

namespace ErrorTest
{
    class Program
    {
        static void Main(string[] args)
        {
            var theList = new List<TestData>() { new TestData { Id = 1, DataField = "nr one" }, new TestData { Id = 2, DataField = "nr two" } };
            var value1 = 1;
            var value2 = 2;
            //set a break point att the if statement and drag debug pointer to row 16, so we end up inside the if statement but its false.
            if (value1 == value2)
            {
                var thenr = 1;
                var tt = theList.FirstOrDefault(x => x.Id == thenr);
            }
        }
    }
    //codebye.com CopyRight
    class TestData
    {
        public int Id { get; set; }
        public string DataField { get; set; }
    }
}

Here is the IL generated


.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size    codebye.com CopyRight   122 (0x7a)
  .maxstack  5
  .locals init ([0] class [mscorlib]System.Collections.Generic.List`1<class ErrorTest.TestData> theList,
           [1] int32 value1,
           [2] int32 value2,
           [3] bool V_3,
           [4] class ErrorTest.Program/'<>c__DisplayClass0_0' 'CS$<>8__locals0',
           [5] class ErrorTest.TestData tt)
  .language '{3F5162F8-07C6-11D3-9053-00C04FA302A1}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}'
// Source File 'C:\Users\ivanbaso\source\repos\CSConsoleApp6\CSConsoleApp6\Program.cs' 
//000009:         {
  IL_0000:  nop
//000010:             var theList = new List<TestData>() { new TestData { Id = 1, DataField = "nr one" }, new TestData { Id = 2, DataField = "nr two" } };
  IL_0001:  newobj     instance void class [mscorlib]System.Collections.Generic.List`1<class ErrorTest.TestData>::.ctor()
  IL_0006:  dup
  IL_0007:  newobj     instance void ErrorTest.TestData::.ctor()
  IL_000c:  dup
  IL_000d:  ldc.i4.1
  IL_000e:  callvirt   instance void ErrorTest.TestData::set_Id(int32)
  IL_0013:  nop
  IL_0014:  dup
  IL_0015:  ldstr      "nr one"
  IL_001a:  callvirt   instance void ErrorTest.TestData::set_DataField(string)
  IL_001f:  nop
  IL_0020:  callvirt   instance void class [mscorlib]System.Collections.Generic.List`1<class ErrorTest.TestData>::Add(!0)
  IL_0025:  nop
  IL_0026:  dup
  IL_0027:  newobj     instance void ErrorTest.TestData::.ctor()
  IL_002c:  dup
  IL_002d:  ldc.i4.2
  IL_002e:  callvirt   instance void ErrorTest.TestData::set_Id(int32)
  IL_0033:  nop
  IL_0034:  dup
  IL_0035:  ldstr      "nr two"
  IL_003a:  callvirt   instance void ErrorTest.TestData::set_DataField(string)
  IL_003f:  nop
  IL_0040:  callvirt   instance void class [mscorlib]System.Collections.Generic.List`1<class ErrorTest.TestData>::Add(!0)
  IL_0045:  nop
  IL_0046:  stloc.0
//000011:             var value1 = 1;
  IL_0047:  ldc.i4.1
  IL_0048:  stloc.1
//000012:             var value2 = 2;
  IL_0049:  ldc.i4.2
  IL_004a:  stloc.2
//000013:             //set a break point att the if statement and drag debug pointer to row 16, so we end up inside the if statement but its false.
//000014:             if (value1 == value2)
  IL_004b:  ldloc.1
  IL_004c:  ldloc.2
  IL_004d:  ceq
  IL_004f:  stloc.3
//000015:             {
//000016:                 var thenr = 1;
//000017:                 var tt = theList.FirstOrDefault(x => x.Id == thenr);
//000018:             }
//000019:         }
//000020:     }
//000021: 
//000022:     class TestData
//000023:     {
//000024:         public int Id { get; set; }
//000025:         public string DataField { get; set; }
//000026:     }
//000027: }
  IL_0050:  ldloc.3
  IL_0051:  brfalse.s  IL_0079
  IL_0053:  newobj     instance void ErrorTest.Program/'<>c__DisplayClass0_0'::.ctor()
  IL_0058:  stloc.s    'CS$<>8__locals0'
//000015:             {
  IL_005a:  nop
//000016:                 var thenr = 1;
  IL_005b:  ldloc.s    'CS$<>8__locals0'
  IL_005d:  ldc.i4.1
  IL_005e:  stfld      int32 ErrorTest.Program/'<>c__DisplayClass0_0'::thenr
//000017:                 var tt = theList.FirstOrDefault(x => x.Id == thenr);
  IL_0063:  ldloc.0
  IL_0064:  ldloc.s    'CS$<>8__locals0'
  IL_0066:  ldftn      instance bool ErrorTest.Program/'<>c__DisplayClass0_0'::'<Main>b__0'(class ErrorTest.TestData)
  IL_006c:  newobj     instance void class [mscorlib]System.Func`2<class ErrorTest.TestData,bool>::.ctor(object,
                                                                                                         native int)
  IL_0071:  call       !!0 [System.Core]System.Linq.Enumerable::FirstOrDefault<class ErrorTest.TestData>(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>,
                                                                                                         class [mscorlib]System.Func`2<!!0,bool>)
  IL_0076:  stloc.s    tt
//000018:             }
  IL_0078:  nop
//000019:         }
  IL_0079:  ret
} // codebye.com CopyRight end of method Program::Main

It seems that IL_005a: nop should be emitted on IL_0053

Answers :

Why do we think this is a compiler issue? The user here is essentially stepping past the closer initializing code. There isn’t much we can do to stop that in the compiler. Seems no different than say moving the cursor past the initialization of a local variable.

the sequence point that’s associated with { should cover the closure initializer (i.e. be emitted at IL offset 0x53 instead of 0x5a), so that when the user moves the IP to { the closure is initialized.

个人理解:这个异常不用处理,不手动拖动断点是不会触发异常的。


CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明NullReferenceException: CS$<>8__locals0 was null
喜欢 (0)
[1034331897@qq.com]
分享 (0)

文章评论已关闭!