Joel
Joel

Reputation: 103

create Dynamic class object

I'm learning C#, and now I got stuck on dynamic objects (if there's such a thing).

I have two Buttons and two TextBoxes on a userform, so what I am trying to do is to instantiate an object each time I click Button1 and assign its name property value to whatever text is in TextBox1. After a few instances I want to retrieve a name value of any created object (something like MessageBox.Show(obj[int.Parse(TextBox2.text)].name)).

The code throws error:

System.NullReferenceException: 'Object reference not set to an instance of an object.'

TEST[] o;

private void Button1_Click(object sender, EventArgs e)
{
    o = new TEST[10];
    o[1].name = textBox1.Text;
}

private void Button2_Click(object sender, EventArgs e)
{
    MessageBox.Show(o[1].xcount.ToString());
}

I want read a property value for a specific object by object index/count.

Upvotes: 0

Views: 97

Answers (5)

Joel
Joel

Reputation: 103

Thanks to everyone, your input helped me to write this awesome program as begginer: int next = 0; TEST[] o = new TEST[10]; private void Button1_Click(object sender, EventArgs e) { o[next] = new TEST { name = textBox1.Text }; next++; } private void Button2_Click(object sender, EventArgs e) { MessageBox.Show(o[int.Parse(textBox2.Text)].name); }

Upvotes: 0

ccdevtam
ccdevtam

Reputation: 1

first, your Button1_Click does reset your o array each click. What you would want to do is to move it out there, probably in an initializing method, or in the constructor. A global declaration will also do.

second, System.NullReferenceException: 'Object reference not set to an instance of an object.' is thrown because you are trying to access an Array slot that is not yet defined.

    o = new TEST[10]; //new array here
    o[1].name = textBox1.Text; //and then you access slot[1] immediately

What you would want to do is to set slot[1] first.

   o[1] = new Test();

To avoid this error in the future, you would want to make sure that a slot is instantiated before accessing it.

   if (slot[i] != null)
   {   slot[i].name = "nam"; }

Upvotes: 0

Prasad Telkikar
Prasad Telkikar

Reputation: 16059

Here you are instantiating array of Test class every time. Create one class (Instead of dynamic) with property called Name, which will store value of textbox1 at every button click.

Use that property to retrieve name when you click Button2

Test[] testArray = new Test[10];
int index = 0;

private void Button1_Click(object sender, EventArgs e)
{
   if(index < 10)  //To avoid ArrayIndexOutOfBound error
   {
      testArray[index++] = new Test() { Name = textBox1.Text };
   }

}
private void Button2_Click(object sender, EventArgs e)
{
    //Read Name of first element in an array
    string firstName = testArray.FirstOrDefault()?.Name;
    MessageBox.Show(firstName);
}


public class Test
{
   public string Name { get; set; }
}

Upvotes: 1

Olivier Jacot-Descombes
Olivier Jacot-Descombes

Reputation: 112259

After you have created the array TEST it contains 10 positions all containing null. You must first create the TEST objects

o = new TEST[10];
// o[1] is null here.
o[1] = new TEST(); // Create object.
o[1].name = textBox1.Text;

Or

o = new TEST[10];
TEST test = new TEST();
test.name = textBox1.Text;
o[1] = test;

Or, with an object initializer

o = new TEST[10];
o[1] = new TEST{name = textBox1.Text};

But note that the array indexes are zero-based. I.e., the first element of the array is o[0] and the last one o[9].

Also, note that your Button1_Click method creates a new array each time and thus discards any values store before.

Upvotes: 0

Sweeper
Sweeper

Reputation: 270790

Your choice of using arrays is one of the correct approaches.

First, you should move the initialisation of the array outside the method, so that you don't create a new array (and hence discarding the old objects) every time you press button 1:

TEST[] o = new TEST[10];
private void Button1_Click(object sender, EventArgs e)
{
    // ...
}

Next, add a variable indicating where the next element should be added to the array:

int next = 0;
TEST[] o = new TEST[10];
private void Button1_Click(object sender, EventArgs e)
{
    // ...
}

Inside Button1_Click, you need to create a TEST object with the name of textBox1.Text, assign it to o[next], and increment next so that the next element can be inserted.

o[next] = new TEST { name = textBox1.Text };
next++;

Try working out how to implement Button2_Click.

Obviously, this program can only store a fixed number of TEST objects. If you want to store an unknown number of objects, you need a List<TEST>:

List<TEST> o = new List<TEST>();
private void Button1_Click(object sender, EventArgs e)
{
    o.Add(new TEST{ name = textBox1.Text });
}

Upvotes: 0

Related Questions