简体   繁体   中英

debuging bug in scope when drag arrow breakpoint

-> Start debug mode -> Reach if(calculate) line -> Drag arrow to next line { -> Reach string sValue = "ABC123"; -> Threw an exception Object reference not set to an instance of an object.

But if i set calculate = true and don't drag arrow and just continue with F10 there is no exception at all. You can see in code, 5 cases when throw exception and when not throw exception. When i define sValue before if block, there is no exception.

Can you explain why throw exception in this situation ?

Steps

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

namespace ConsoleApplication1
{
    class Program
    {
        public static List<SaleLineItem> SaleItems = new List<SaleLineItem>();

        static void Main(string[] args)
        {
            SaleItems.Add(new SaleLineItem { ItemId = "ABC123", NetAmount = 2 });
            SaleItems.Add(new SaleLineItem { ItemId = "ABC123", NetAmount = 3 });

            try
            {
                bool calculate = false;
                // string sValue = "ABC123";

                if (calculate)
                {
                    string sValue = "ABC123";
                    decimal total = 0;

                    #region Exception
                    total = SaleItems.Where(t => t.ItemId != sValue).Count();
                    // total = SaleItems.Where(t => t.ItemId != sValue).Sum(t => t.NetAmountWithTax); 
                    // var newSaleItems = SaleItems.FirstOrDefault(t => t.ItemId != sValue);
                    #endregion

                    #region No Exception
                    // string newValue = sValue;
                    // var newSaleItems = SaleItems.FirstOrDefault();
                    #endregion
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }

    [Serializable]
    public class SaleLineItem
    {
        public string ItemId { get; set; }
        public decimal NetAmount { get; set; }
    }
}

I might have found a reason why that happens.

First of all I beoke down your code to see what it needs to get that Exception and ended up like this:

List<string> SaleItems = new List<string>();
var test = false;

if(test)
{
    var sValue = "ABC123";

    SaleItems.Count(t => t != sValue);
}

This produces the exact same error, as you described.

So my guess was this could be a problem with the compiler that optimized something, so I took a look at the Intermediate Language (IL) produced by this code. Here's the part that I think is interesting: (Note: The lines starting with // are just comments for visualisation to which part of the code the comments belong)

//000013: 
//000014:           if(test)
  IL_0009:  ldloc.1
  IL_000a:  stloc.2
//000015:           {
//000016:               var sValue = "ABC123";
//000017:               
//000018:               SaleItems.Count(t => t != sValue);
//000019:           }
//000020:       }
//000021:   }
//000022: }
  IL_000b:  ldloc.2
  IL_000c:  brfalse.s  IL_0034
  IL_000e:  newobj     instance void TestConsoleApplciation_delete_.Program/'<>c__DisplayClass0_0'::.ctor()
  IL_0013:  stloc.3
//000015:           {
  IL_0014:  nop
//000016:               var sValue = "ABC123";
  IL_0015:  ldloc.3
  IL_0016:  ldstr      "ABC123"

The breakpoint is set at the if(test) in Line 14, which is in IL the line that starts with IL_0009: . Now, if you drag the debugger to the next line (Line 15), it will internally jump to the line IL_0014: and continue from there, so the lines between are skipped.

The problem there is now that the next command that is executed is ldloc.3 at line IL_0015: (ignoring the nop command, which does nothing) and this command tries to load the variable that is stored at line IL_0013: but that command was not executed, so it throws the NullReferenceException because there is nothing to load.

Note: I do not now if this is the real reason why the Exception is thrown but I think it is a pretty reasonable guess.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM