简体   繁体   中英

Why does this code throw a NullReferenceException? Is it because of the ref string?

I am kind of confused here . I have a program that has been running for years , Just yesterday when i made some few changes in one part of the file. It begin throwing "NullReferenceException" on ref string method.

   string message = "";

   this.GetAuditMessage(grpAccess, ref message);


    private void GetAuditMessage(Control c_parent, ref string message)
    {
        foreach(Control c in c_parent.Controls) 
        {       
            Console.WriteLine(c.Name);
            if (c.GetType().ToString().Equals("System.Windows.Forms.Panel"))
            {
                try
                {
                    string str = message;
                    GetAuditMessage(c, ref str);
                }
                catch(Exception nu) 
                {
                    Console.WriteLine(nu.InnerException.ToString());
                }


            }
            else if (c.GetType().ToString().Equals("System.Windows.Forms.TextBox") ||
                c.GetType().ToString().Equals("System.Windows.Forms.ComboBox"))
            {
                int n = c.Tag.ToString().IndexOf(":");
                int len = c.Tag.ToString().Length;

                string controlName = c.Tag.ToString().Substring(0, n);
                string oldSetting = c.Tag.ToString().Substring(n + 1, len - (n + 1));

                if (!oldSetting.Equals(c.Text))
                {
                    message += "Change " + controlName + "' from '" + oldSetting + "' to '" + c.Text + ".'\n";
                }
            }
        }
    }

When i put a break at GetAuditMessage(c, ref message) . It throws exception . However, i modify to something like below.

string str = message;
GetAuditMessage(c, ref str);

The above works fine. I then try and run the old version . It run fine with no exception. Please can some one explain why the exception ? Please why does it throw now and doesn't before ? How do i best fix this ?

My best guess here is that one of the c.Tag is null , or not quite in the expected format - and your "fix" is unrelated (although it does stop it working correctly). You would do better to pass in a StringBuilder , btw, and use that to build up the composed string; no need for ref then.

It doesn't help that your catch block also does something careless, by accessing .ToString() on something that could be null - ie InnerException . So; if we assume that some Tag is not a string or not in the expected format: it would throw either a NullReferenceException or an ArgumentOutOfRangeException , without an InnerException ; your catch block, if it is hit (ie if this isn't the outermost control - the form itself), would in turn throw a NullReferenceException .

If it was me:

var sb = new StringBuilder();
this.GetAuditMessage(grpAccess, sb);
var message = sb.ToString();


private void GetAuditMessage(Control c_parent, StringBuilder sb) {
    foreach(Control c in c_parent.Controls)  {       
        Console.WriteLine(c.Name);
        if (c is System.Windows.Forms.Panel) {
            try {
                GetAuditMessage(c, sb);
            } catch(Exception nu)  {
                Console.WriteLine(nu.Message);
            }
        }
        else if (c is System.Windows.Forms.TextBox ||
            c is System.Windows.Forms.ComboBox)
        {
            string tag = c.Tag == null ? "" : c.Tag.ToString();
            int n = tag.IndexOf(":");
            if(n < 0) continue;
            int len = tag.Length;

            string controlName = tag.Substring(0, n);
            string oldSetting = tag.Substring(n + 1, len - (n + 1));

            if (!oldSetting.Equals(c.Text))
            {
                sb.AppendFormat("Change {0} from '{1}' to '{2}'.",
                    controlName, oldSetting, c.Text).AppendLine();
            }
        }
    }
}

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