Resolved Field is never assigned to, and will always have its default value as null

Anonymous

Well-known member
Joined
Sep 29, 2020
Messages
84
Programming Experience
Beginner
I want to build a console application where I am storing a list of cars linked to a person's id . My class is -
C#:
class Person
{
    public int PersonID
    {
        get;
        set;
    }

    public string cars
    {
        get;
        set;
    }
    public List<string> carlist
    {
        get;
        set;
    } 
}
I am getting a null pointer exception( object reference object reference not set to an instance of an object) when I am trying to add cars to the list. Please see the code below-
C#:
do
{
    Person person = new Person();
    PersonDetails personDetails = new PersonDetails();

    Console.WriteLine("Enter the Person ID");
    
    person.PersonID = Convert.ToInt32(Console.ReadLine());

    char response;

    do
    {
        Console.WriteLine("Enter his cars");
        
        person.cars = Console.ReadLine();
        person.carlist.Add(person.cars);

        Console.WriteLine("More cars ? Press y to contine");
        
        response = Convert.ToChar(Console.ReadLine());
    } while (response == 'y');

    personList.Add(person);

    Console.WriteLine("Press y if you wannt add data");
    
    ch = Convert.ToChar(Console.ReadLine());
} while (ch == 'y');

I am also getting a warning for public List<string> carlist that it is not assigned and the default value will always be null.
How do I fix this ?
 
Last edited by a moderator:
Please use the editor to insert code:

insertcode.png
 
The two error messages are related. The second one is telling you that you never assign anything to your carlist property and so it will always be null. That being the case, why should it be a surprise that you get a NullReferenceException here:
C#:
person.carlist.Add(person.cars);
How can you call Add on an object that doesn't exist? The proper way to implement a collection property is like this:
C#:
class Person
{
    public int PersonID
    {
        get;
        set;
    }

    public string Cars
    {
        get;
        set;
    }

    public List<string> CarList => new List<string>();
}
What that does is create a new List<string> object and assign it to the property when the parent object is created and it also makes the property read-only, so the calling code can add and remove items in that list but it cannot replace the whole list with a new one.
 
Note that that expression-bodied property syntax is only supported in fairly recent versions of C#. In older versions you would have done this:
C#:
private List<string> _carList = new List<string>();

public List<string> CarList
{
    get
    {
        return _carList;
    }
}
That declares and initialises a backing field explicitly and then returns that field value in the property getter. The code in my previous post is basically expanded to that when compiled.
 
Thanks but I am now not able to add objects to my list (carlist)

C#:
 do
                {
                    Console.WriteLine("Enter his cars");
                    person.cars = Console.ReadLine();
                    person.carlist.Add(person.cars);

                    Console.WriteLine("More cars ? Press y to contine");
                    response = Convert.ToChar(Console.ReadLine());
                } while (response == 'y');

                personList.Add(person);

                Console.WriteLine("Press y if you wannt add data");
                ch = Convert.ToChar(Console.ReadLine());
            } while (ch == 'y');
 
Sorry, my mistake. Wrong syntax. This:
C#:
public List<string> CarList => new List<string>();
should have been this:
C#:
public List<string> CarList { get; } = new List<string>();
As it was, it was creating and returning a new list every time you got the property value instead of creating it once at the start and returning that same list every time.
 
Now, the data is stored in the list but I can't display the elements. Don't know what must be the cause - I am using Linq to group the cars by Person id . Person ID gets printed successfully but for the elements I get system.collections.generic.list 1 system.string. Is something wrong with the linq expression( apologies as I am new to it).
C#:
  Console.WriteLine("Grouping people with cars");
            var listgroupwithID = from result in personList
                                  group result by result.PersonID ;

            foreach (var groupresult in listgroupwithID)
            {
                Console.WriteLine("Id :" + groupresult.Key);

                foreach (var name in groupresult)
                    Console.WriteLine("Cars : " + name.carlist);
 
Last edited:
No there is nothing wrong with the LINQ. The issue is just forgetting the in C#, most of the objects' ToString() implementations just return their type name, and that collection type objects, like lists, don't automatically return the collection contents when you call ToString(). Console.WriteLine() effectively calls ToString().
 
Last edited:
If you want to actually display a String containing all the items in a list then you actually have to create such a String. It won't happen automatically. String.Join is usually the way to do that:
C#:
Console.WriteLine("Cars : " + string.Join(", ", name.carlist));
That will create a single, comma-delimited String containing all the items in the list.

Also, please start using appropriate casing. PersonID is good but, as I did in my code, you should use CarList rather than carlist. Generally speaking, only local variables and private fields should start with a lower-case letter and each word in a multi-word identifier should also start with with upper case. You can see it in all the types and members from the Framework that you use. You should do the same.

For the record, you generally shouldn't end a name with "List" either. There may be valid reasons but not really in this case. A collection property should generally just be the plural of whatever it contains. In this case, Cars or CarNames would be more appropriate.
 
Back
Top Bottom