Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
450 views
in Technique[技术] by (71.8m points)

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

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: enter image description 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: enter image description here to here: enter image description 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 sv

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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 enter image description here

Here is my debug configuration

enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...