c# - Code that HAS NOT RUN YET is causing an exception? How is this even possible?

﹥>﹥吖頭↗ 提交于 2019-12-13 09:48:20

问题


So I am completely stumped on this one. I am getting an error Object reference not set to an instance of an object. and I am not sure why.

I have a class FILE

    public class FILE
    {
        private string _fileName;
        public string fileName
        {

            get
            {
                if (!Settings.Values.CaseSensitive)
                    return this._fileName.ToUpper();
                else
                    return this._fileName;
            }
            set
            {
                if (!Settings.Values.CaseSensitive)
                    this._fileName = value.ToUpper();
                else
                    this._fileName = value;
            }
        }
        public string folderName { get; set; }
        public byte[] fileHashDigest { get; set; }
    }

I am creating an instance like:

FILE test1233;      
test1233 = new FILE(); // <---- Ex thrown here!? Why???    
test1233.fileName = "";
folderName = "";
fileHashDigest = new byte[1];

As soon as the variable is placed on the stack, it throws an exception. BUT... if I remove all refrences to this variable on code further down (WHICH HAS NOT YET BEEN EXECUTED IN DEBUGMODE!!!) then no exception gets thrown. What on earth is going on here?

For refrence, here is the method in it's entirety:

    private bool IsFolderOverride(FileCollection zipFILEList, DataTable exceptionTableFileList, DataRow currentRow, ref DataTable detectedFolderRenames)
    {
        bool foundInExceptionTable = false;
        foreach (DataRow exRow in exceptionTableFileList.Rows)
        {
            if (exRow["FILE_NAME"].ToString().ToUpper() == currentRow["FILE_NAME"].ToString().ToUpper() &&
                (decimal)exRow["WINDOW_GROUP_ID"] == (decimal)currentRow["WINDOW_GROUP_ID"])
            {
                string name = exRow["FILE_NAME"].ToString().ToUpper();
                string folder = exRow["FOLDER_NAME"].ToString().ToUpper();
                byte[] digest = (byte[])exRow["FILE_HASH_DIGEST"];
                CopyCat exCopyCat = new CopyCat();
                exCopyCat.fileName = name;
                exCopyCat.folderName = folder;
                exCopyCat.fileHashDigest = digest;

                //HAS AN EXCEPTION!
                FILE test1233 = new FILE();
                test1233.fileName = "";
                test1233.folderName = "";
                test1233.fileHashDigest = new byte[1];

                //NO EXCEPTION THROWN
                FILE test = new FILE();
                bool test9 = zipFileList.Contains(test1233);


                test.fileName = name;
                test.folderName = folder;
                test.fileHashDigest = digest;

                FILE test123 = new FILE();

                if (zipFileList.Contains(test1233)) // Exact match found in zip in old folder from exception table.
                {
                    FILE exists = zipFileList.Where(f => f.fileName == test1233.fileName &&
                                          f.fileHashDigest.SequenceEqual(test1233.fileHashDigest)).First();
                    object[] items = exRow.ItemArray;
                    Array.Resize(ref items, items.Length + 4);
                    items[items.Length - 1] = "Y";
                    items[items.Length - 2] = exists.folderName;
                    items[items.Length - 3] = test1233.folderName;
                    items[items.Length - 4] = "Folder Override";
                    if (detectedFolderRenames.Rows.Count == 0 || !detectedFolderRenames.Rows.Contains(items[0]))
                        detectedFolderRenames.Rows.Add(items);

                    foundInExceptionTable = true;
                    break;
                }
                else if (zipFileList.ContainsPartially(test1233)) // Match in zip with Different Hash found from ex table.
                {
                    FILE exists = zipFileList.Where(f => f.fileName == test1233.fileName).First();
                    object[] items = exRow.ItemArray;
                    Array.Resize(ref items, items.Length + 4);
                    items[items.Length - 1] = "N";
                    items[items.Length - 2] = exists.folderName;
                    items[items.Length - 3] = test1233.folderName;
                    items[items.Length - 4] = "Folder Override";
                    if (detectedFolderRenames.Rows.Count == 0 || !detectedFolderRenames.Rows.Contains(items[0]))
                        detectedFolderRenames.Rows.Add(items);

                    foundInExceptionTable = true;
                    break;
                }
            }
            else
                continue;
        }
        return foundInExceptionTable;
    }

UPDATE: I am still working on an example for you, but in the mean time here is potentially helpful information:

test1233' threw an exception of type 'System.NullReferenceException'
Data: {System.Collections.ListDictionaryInternal}
HResult: -2147467261
HelpLink: null
InnerException: null
Message: "Object reference not set to an instance of an object."
Source: null
StackTrace: null
TargetSite: null

The Data: {System.Collections.ListDictionaryInternal} part is a little interesting to me, my class does not use any dictionary lists.

UPDATE #2: Ok, I have produced a reproducible sequence of steps for others to try. On your machines, it may be just fine, like Jon Skeet said, it might be my debug environment settings but please try and let me know. Here are the steps to reproduce.

  1. Open console app project and copy paste code below.
  2. Set a break point here:
  3. First run code past break point, it works! :D
  4. Then run code again but this time STOP at the break point and DRAG the executing statement cursor INTO the if statement from here: to here:

There it is! So the error was caused from my method of testing, but does this make any sense or is this just me on my machine?

CODE:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace testapp
{
    class Program
    {
        static void Main(string[] args)
        {
            FILECollection randomCollection = new FILECollection();
            // Fill with junk test data:
            for(int i = 0; i<10; i++)
            {
                FILE junkfile = new FILE() { fileName = i.ToString(), folderName = i.ToString(), fileHashDigest = new byte[1] };
                randomCollection.Add(junkfile);
            }

            if (true)
            {
                Console.WriteLine("testing this weird exception issue...");
                FILE test;
                test = new FILE();
                test.fileName = "3";
                test.folderName = "3";
                test.fileHashDigest = new byte[1];

                FILE exists = randomCollection.Where(f => f.fileName == test.fileName &&
                                              f.fileHashDigest.SequenceEqual(test.fileHashDigest)).First();
            }
        }
    }


    public class FILE
    {
        public FILE() { _fileName = "";}
        private string _fileName;
        public string fileName
        {

            get
            {
                    if (false)
                        return this._fileName.ToUpper();
                    else
                        return this._fileName;
            }
            set
            {

                    if (false)
                        this._fileName = value.ToUpper();
                    else
                        this._fileName = value;
            }
        }
        public string folderName { get; set; }
        public byte[] fileHashDigest { get; set; }
    }

    public class FILECollection : IEnumerable<FILE>, ICollection<FILE>
    {
        private HashSet<FILE> svgHash;
        private static List<FILE> PreallocationList;
        public string FileName = "N/A";

        /// <summary>
        /// Default Constructor, will not 
        /// preallocate memory.
        /// </summary>
        /// <param name="PreallocationSize"></param>
        public FILECollection()
        {
            this.svgHash = new HashSet<FILE>();
            this.svgHash.Clear();
        }

        /// <summary>
        /// Overload Constructor Preallocates
        /// memory to be used for the new 
        /// FILE Collection.
        /// </summary>
        public FILECollection(int PreallocationSize, string fileName = "N/A", int fileHashDigestSize = 32)
        {
            FileName = fileName;
            PreallocationList = new List<FILE>(PreallocationSize);
            for (int i = 0; i <= PreallocationSize; i++)
            {
                byte[] buffer = new byte[fileHashDigestSize];
                FILE preallocationSVG = new FILE()
                {
                    fileName = "",
                    folderName = "",
                    fileHashDigest = buffer
                };
                PreallocationList.Add(preallocationSVG);
            }
            this.svgHash = new HashSet<FILE>(PreallocationList);
            this.svgHash.Clear(); // Capacity remains unchanged until a call to TrimExcess is made.
        }

        /// <summary>
        /// Add an FILE file to 
        /// the FILE Collection.
        /// </summary>
        /// <param name="svg"></param>
        public void Add(FILE svg)
        {
            this.svgHash.Add(svg);
        }

        /// <summary>
        /// Removes all elements 
        /// from the FILE Collection
        /// </summary>
        public void Clear()
        {
            svgHash.Clear();
        }


        /// <summary>
        /// Determine if the FILE collection
        /// contains the EXACT FILE file, folder, 
        /// and byte[] sequence. This guarantees 
        /// that the collection contains the EXACT
        /// file you are looking for.
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public bool Contains(FILE item)
        {
            return svgHash.Any(f => f.fileHashDigest.SequenceEqual(item.fileHashDigest) &&
                                    f.fileName == item.fileName &&
                                    f.folderName == item.folderName);
        }

        /// <summary>
        /// Determine if the FILE collection 
        /// contains the same file and folder name, 
        /// byte[] sequence is not compared. The file and folder
        /// name may be the same but this does not guarantee the 
        /// file contents are exactly the same. Use Contains() instead.
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public bool ContainsPartially(FILE item)
        {
            return svgHash.Any(f => f.fileName == item.fileName &&
                                    f.folderName == item.folderName);
        }

        /// <summary>
        /// Returns the total number
        /// of FILE files in the Collection.
        /// </summary>
        public int Count
        { get { return svgHash.Count(); } }

        public bool IsReadOnly
        { get { return true; } }

        public void CopyTo(FILE[] array, int arrayIndex)
        {
            svgHash.CopyTo(array, arrayIndex);
        }

        public bool Remove(FILE item)
        {
            return svgHash.Remove(item);
        }

        public IEnumerator<FILE> GetEnumerator()
        {
            return svgHash.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return svgHash.GetEnumerator();
        }
    }
}

I think either I am debugging in a terribly wrong way, or Microsoft should take a look at this. It's like future code is breaking current code...which is impossible!


回答1:


I tried to execute the code in a console app and is working, can you give more details? Answers about the Settings initialization doesn't make sense here at this point because you should be able to create the instance of FILE. Once you try to assign(set) or request(get) then you are dealing with fileName property. I am not seeing why you get the exception when you create the instance.

 static void Main(string[] args)
        {
            FILE test1233;
            test1233 = new FILE(); // <---- Ex is not thrown here!?                           test1233.fileName = "";
            test1233.folderName = "";
            test1233.fileHashDigest = new byte[1];
        }

public class FILE
    {
        private string _fileName;
        public string fileName
        {

            get
            {
                if (YOUR SETTING CONDITION HERE)
                    return this._fileName.ToUpper();
                else
                    return this._fileName;
            }
            set
            {
                if (YOUR SETTING CONDITION HERE)
                    this._fileName = value.ToUpper();
                else
                    this._fileName = value;
            }
        }
        public string folderName { get; set; }
        public byte[] fileHashDigest { get; set; }
    }

see the cursor on the print screen

Here is my debug configuration



来源:https://stackoverflow.com/questions/39981674/c-sharp-code-that-has-not-run-yet-is-causing-an-exception-how-is-this-even-po

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!