0

Here is a basic math programm in which all I simply want to do is save these values num1 and num2 into the list saved within the class. This keeps throwing this error when the program gets to the line in which it is added.

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

I know that what I have done wrong is something obvious but I am not sure at the moment.

class Program
{
    static void Main(string[] args)            
    {
        PromptAndAddUserNums();
    }

    public static void PromptAndAddUserNums() {
        bool goToken = true;
        UserInfo userInfo = new UserInfo();

        while (goToken)
        {
            Console.WriteLine("insert 1st number");
            int num1 = int.Parse(Console.ReadLine());

            Console.WriteLine("insert 2nd number");
            int num2 = int.Parse(Console.ReadLine());

            userInfo.NumList.Add(num1);
            userInfo.NumList.Add(num2);

            Console.WriteLine("do you wanna add another number?(yes or no)");
            string userChoice = Console.ReadLine().ToUpper();

            if (userChoice == "YES")
            {
                continue;
            }
            else if (userChoice == "NO")
            {
                goToken = false;
            }
        }
    }
}

class UserInfo{    
    public  List<int> NumList  { get; set; }
    public UserInfo()
    {
    }
}
Roxana Sh
  • 294
  • 1
  • 3
  • 14
  • `public List NumList` is never initialized with a `new List` – UnholySheep Dec 01 '19 at 10:09
  • 3
    Does this answer your question? [What is a NullReferenceException, and how do I fix it?](https://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – UnholySheep Dec 01 '19 at 10:09
  • where would i intialise when using a get set. I understand the null refrence exception but do not understand where to intialise it. As this is usually done when it is created.But when using this get set it was not intialised at creation. – Henry Peters Dec 01 '19 at 10:12
  • 5
    Well you can write `NumList { get; set; } = new List();`, or put it in the constructor, or set it in the calling code when you create the new `UserInfo`. Note that if you *do* understand what's wrong, you should specify that in the question - at the moment it sounds like you don't know why the exception is occurring. – Jon Skeet Dec 01 '19 at 10:13

1 Answers1

1

When you create a variable that has a type of some class, it has a default value of null as it's a reference type. You should initialize it with the new keyword. Like what you did with:

UserInfo userInfo = new UserInfo();

You should do the same with the List<int>, the best place in my opinion would be in the constructor:

public UserInfo()
{
    NumList = new List<int>();
}

This way, when you create a new UserInfo object, the constructor is called and NumList would be initialized to a new List(). So when you do userInfoObject.NumList.Add(...), the Add method would be appliced to an initialized List, instead of null.


Edit based on Jon Skeet comment:

You can use the C# 6 feature called Auto-property initializer to give an initial value for your property. Also it seems that you don't need a setter for your property, so you can do it like:

public List<int> NumList { get; } = new List<int>();

Some comments NOT related to your problem:

  • Be consistent in your coding-style, you're using allman braces (i.e, put braces on newlines) everywhere except for PromptAndAddUserNums and UserInfo class.

  • I'd use implicitly typed local variables if the type is obvious from the assignment. (var userInfo = new UserInfo(); instead of UserInfo userInfo = new UserInfo();)

  • I don't think you really need a boolean goToken, I'd simplify the code to be like the following:

    class Program
    {
        static void Main(string[] args)            
        {
            PromptAndAddUserNums();
        }
    
        public static void PromptAndAddUserNums()
        {
            var userInfo = new UserInfo();
    
            while (true)
            {
                Console.WriteLine("insert 1st number");
                int num1 = int.Parse(Console.ReadLine());
    
                Console.WriteLine("insert 2nd number");
                int num2 = int.Parse(Console.ReadLine());
    
                userInfo.NumList.Add(num1);
                userInfo.NumList.Add(num2);
    
                Console.WriteLine("do you wanna add another number?(yes or no)");
                string userChoice = Console.ReadLine().ToUpper();
    
    
                if (userChoice == "NO")
                {
                    break;
                }
            }
        }
    }
    
    class UserInfo
    {
        public List<int> NumList { get; } = new List<int>();
    }
    
Youssef13
  • 3,836
  • 3
  • 24
  • 41
  • 1
    Or just remove the parameterless constructor declaration, and write `public List NumList { get; set; } = new List();` - or make it a read-only property: `public List NumList { get; } = new List();`. There's no indication that the OP really needs to be able to set it. – Jon Skeet Dec 01 '19 at 10:14