简体   繁体   中英

button array NullReferenceException was unhandled

First of all i'm new in here and new with csharp. just exhausted while doing some exercises for learning csharp. cant find a solution why i get the error "NullReferenceException was unhandled" and

1) How to overcome this? according to my researches its related with initialisation but couldnt make it. i debug and watched the values all buttons gets gets null values is it because of this? how can i solve it? what to do? which code to add?

(***all informing knowledge about class initialisations and arrays and null stuffs are welcome. i wanna learn all the points and wanna be expert :P and people can optimize the code as well. all extra informations are welcome.)

2) And why compiler doesnt show error but error comes while running the code?

ok now i have the code blow

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace temp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Button[] btn = new Button[5];

            for (int i = 0; i < 5; i++)
            {
                btn[i] = new Button();
                btn[i].Width = 50;
                btn[i].Height = 50;
                flowLayoutPanel1.Controls.Add(btn[i]);
                btn[i].Click += new EventHandler(btn_Click);
            }
        }

        void btn_Click(object sender, EventArgs e)
        {
            Button[] btn = sender as Button[];
            btn[3].Text = "button name changed";  // here problems occurs
            //btn[3].BackColor = Color.Red;   // here problems occurs
            // btn[3].PerformClick();    // here problems occurs
        }
    }
}

it should be:

void btn_Click(object sender, EventArgs e)
{
    Button btn = sender as Button;
    btn.Text = "button name changed";  // here problems occurs
}

the sender is the button itself, not the array

UPDATE ACCORDING TO THE COMMENT:

you should do something like this:

public partial class Form1 : Form
{
    private Button[] m_ButtonsArray;

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        m_ButtonsArray = new Button[5];

        for (int i = 0; i < 5; i++)
        {
            m_ButtonsArray [i] = new Button();
            m_ButtonsArray [i].Width = 50;
            m_ButtonsArray [i].Height = 50;
            flowLayoutPanel1.Controls.Add(m_ButtonsArray [i]);
            m_ButtonsArray [i].Click += new EventHandler(btn_Click);
        }
    }

    void btn_Click(object sender, EventArgs e)
    {
        m_ButtonsArray[3].Text = "button name changed";  // here problems occurs
    }
}

UPDATE - Changing the 2nd button when the 5th button was clicked:

public partial class Form1 : Form
{
    private Button[] m_ButtonsArray;

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        m_ButtonsArray = new Button[5];

        for (int i = 0; i < 5; i++)
        {
            m_ButtonsArray [i] = new Button();
            m_ButtonsArray [i].Width = 50;
            m_ButtonsArray [i].Height = 50
            m_ButtonsArray [i].Tag = i;;
            flowLayoutPanel1.Controls.Add(m_ButtonsArray [i]);
            m_ButtonsArray [i].Click += new EventHandler(btn_Click);
        }
    }

    void btn_Click(object sender, EventArgs e)
    {
        Button btn = (Button)sender;
        if (((int)btn.Tag) == 5)
        {
           m_ButtonsArray[2].Text = "your text here";
        }
    }
}

explanation: when i create the button, i add the index as a tag (the button knows it's index with the Tag property) when a button is clicked, i check the sender object - casting it to Button , for the index that kept in the Tag . if the Tag value is 5 then i reference the second button (i can reference it though m_ButtonsArray ) and change the values of it

You can solve like that too...it's so similar for eyossi's solution

public partial class Form1 : Form { private

public Form1()
{
    InitializeComponent();
}
Button[] m_Buttons = Array new Button[5];

private void Form1_Load(object sender, EventArgs e)
{
    for (int i = 0; i < 5; i++)
    {
        m_ButtonsArray [i] = new Button();
        m_ButtonsArray [i].Width = 50;
        m_ButtonsArray [i].Height = 50;
        flowLayoutPanel1.Controls.Add(m_ButtonsArray [i]);
        m_ButtonsArray [i].Click += new EventHandler(btn_Click);
    }
}

void btn_Click(object sender, EventArgs e)
{
    m_ButtonsArray[3].Text = "button name changed";  // here problems occurs
}

}

This code is where the problem begins:

Button[] btn = sender as Button[];

At compile time there is no indication to the compiler that the sender of type object won't cast to an array of Button s. But at runtime it won't cast as such, because it's not an array. It's just a Button :

Button btn = sender as Button;

The handler method ( btn_Click ) isn't singularly handling all buttons at the same time, but rather each one individually. When a button is clicked, that button by itself invokes the handler method.

(Others already answered correctly why this exception is thrown)

The error can't be shown by the compiler because you are forcing a cast (using as ) from an object to something else. The compiler doesn't know what the object is and so can't know that an error will happens.

If you call manually the method in your code and pass it an array of buttons as the first argument the code won't crash.

A good thing in this case would have been to use a standard cast instead of as the exception thrown would have been a lot more explicit and would have happened on the correct line instead of letting a null value propagate and fail latter.

A small remark on your code is that your array is useless, you don't use it anywhere and it will be removed from memory as soon as the load function finish executing (Well not exactly but you could read about the Garbage collector if you want more details).

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