0

I would like to ask some rather basic question (I presume) the answer to which seems to elude me. In the following code I am trying to load an array with a csv file (; separated) that contains two columns (string Name, int Score). For simplicity I have commented out the loop I want to use to transfer this file onto an array and I am just loading the 2nd element. For some reason unless I use (scoreobj[1] = new HighScore();) I get a null reference. Why do I need to do that? Haven't I already initialized the scoreobj[] object at the beginning?

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

namespace WindowsFormsApp1
{
   public class HighScore
   {
      public string Name { get; set; }
      public int Score { get; set; }

      public static void LoadHighScores(string filename)
      {
         string[] scoredata = File.ReadAllLines("C:/Users/User/Desktop/Test.csv");
         HighScore[] scoreobj = new HighScore[scoredata.Length];
         scoreobj[1] = new HighScore();
         scoreobj[1].Name = scoredata[1].Split(';')[0];

         //for (int index = 0; index < scoredata.Length; index++)
         //{
         //   scoreobj[index].Name = scoredata[index].Split(',')[0];
         //   scoreobj[index].Score = Convert.ToInt32(scoredata[index].Split(';')[1]);

         //}

         Console.WriteLine(scoreobj[1].Name);
      }
   }
}
11
  • 5
    Because just declaring an index of a specific size does not create any element of type HighScore. You could even create an instance of a derived class and put it into the exact same array. How would the compilr in this case know which class you want to instantiate? It can´t and thus won´t. So you have to create the instance yourself. But even without a derived class, your constructgor may have paramaters, which compiler can´t guess - e.g. new HighScore(name, score). Commented Dec 9, 2019 at 10:14
  • 4
    This answer describes exactly why you have experienced this behaviour: stackoverflow.com/a/15300089/2169762 Commented Dec 9, 2019 at 10:18
  • 2
    Haven't I already initialized the scoreobj[] object at the beginning ...yes, you have. But that just initialises the array, it doesn't initialise the contents (at least not beyond setting some default values for them, which, for classes etc is always null). Commented Dec 9, 2019 at 10:21
  • 1
    Bear with me on this....I am trying to get into OOP for the past months.... I do realize that I have initialized the object scoreobj with null values and I have reserved a place in memory. Doesnt this mean I have created an instance of the Highscore class? Commented Dec 9, 2019 at 10:23
  • 1
    an array is just a collection that can store a bunch of elements of a specific type. Just because you have a bag does not mean you have any potatoes in it, does it? Of course you have to go to the market and put some potatoes in. Commented Dec 9, 2019 at 10:30

2 Answers 2

5

Because just declaring an index of a specific size does not create any element of type HighScore,. Instead you just reserve some memory. In other words: just because you have a bag does not put any potatoes in it. You have to go to the market and put potatoes into your bag yourself.

You could even create an instance of a derived class and put it into the exact same array. How would the compiler in this case know which class you want to instantiate?

class Foo { ... }
class Bar { ... }

var array = new Foo[3]; // how would anyone know if you want three Foo-instances or 3 Bar-instances? or a mix?

The compiler can't know which type you want to instantiate and thus won't create those instances. So you have to create the instance yourself.

But even without a derived class, your constructor may have parameters, which compiler can't guess:

class HighScore
{
    public HighScore(string name, int score) { ... }
}

var array = new HighScore[3]; // how to set the parameters for the instances???

That's why your object just contains no instances, but just the types default-value, which is null for reference-types.

Sign up to request clarification or add additional context in comments.

Comments

1

HighScore[] scoreobj = new HighScore[scoredata.Length]; creates an array of the specified length (scoredata.Length), but containing no objects.

Yo need to assign an object at each index, which could be done as follows:

for (int i = 0; i < scoredata.Length; i++)
{
    scoreobj[i] = new HighScore();
    scoreobj[i].Name = scoredata[i].Split(';')[0];
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.