2

So I have class Group that contains a list of Users. Every time I try to add a user to the list the compiler alerts me that "Object reference not set to an instance of an object". Can someone help show me where I am going wrong with this. Thanks.

class User{
    public string UserName {
        get;set;
    }
    public User(){
    }

    public User(User u){
        UserName = u.UserName;
    }

}

class Group{
    public string GroupName {
        get;set;
    }

    public List<User> Users {
        get;set;
    }

    public Group(){

    }
}

class MainClass
{
    public static void Main (string[] args)
    {
        Group g = new Group ();
        g.GroupName = "First Group";
        g.Users.Add(new User(){ UserName = "Sam" });
    }
}
FrancoCC
  • 31
  • 2
  • Possible duplicate of [What is a NullReferenceException, and how do I fix it?](http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – Eugene Podskal Jun 25 '16 at 16:16
  • anyone can solve my Problem? This Question http://stackoverflow.com/questions/38030136/how-can-i-print-derived-classes-of-marshalbyrefobject-class – Iman Mostafaei Jun 25 '16 at 16:44

3 Answers3

3

You have to create List<User> instance, before adding an items into it, e.g.

   class Group{
     public string GroupName {
       get;set;
     }

     // I doubt if you want public "set" here: do you really want to assign a list?
     public List<User> Users {
       get;
       private set;
     }

     public Group() {
       // you have to create the list instance   
       Users = new List<User>();
     }
   }
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
  • 1
    Starting with C# 6.0 you can write `public List Users { get; } = new List();` – Olivier Jacot-Descombes Jun 25 '16 at 16:22
  • @Olivier Jacot-Descombes: Thank you! I see. But C# 6.0 syntax been succinct is often too difficult to digest for inexperienced developers (what's going on? Read only property assigned in some weird way??) that's why I've preferred longer implementation in the answer. – Dmitry Bychenko Jun 25 '16 at 16:27
  • 1
    This is a getter-only auto-implemented property. You either assign it a value using an initializer (as above) or assign it a value in the construtor. I.e., you can simply drop the `private set;` part and still initialize it as you did. – Olivier Jacot-Descombes Jun 25 '16 at 16:32
1

You can initialize the Users property by creating a new List<User> and assigning it to the property in the constructor. That way you ensure that the list exists as soon as the Group does.

class Group{
    public string GroupName {
        get;set;
    }

    public List<User> Users {
        get; private set;
    }

    public Group(){
        Users = new List<User>();
    }
}

It's also a good idea to make the Users property read only (making set private.) You want to be be able to add users to the list, but you probably don't want someone to be able to do this:

var group = new Group();
group.Users = null;

or

group.Users = new List<User>();

This way you have more control over what other classes can or can't do. And you'll know that the Users property, the list itself, will never be null.

Scott Hannen
  • 27,588
  • 3
  • 45
  • 62
0

In this line g.Users.Add(new User(){ UserName = "Sam" }); You have to check first that the g.Users is not null, like this:

if(g.Users==null)
   g.Users = new List<Users>();
g.Users.Add(new User(){ UserName = "Sam" });
MoustafaS
  • 1,991
  • 11
  • 20
  • 1
    That's not thread safe (but in most cases that should not be a problem). A better solution could be to create the list instance in the `Group`constructor. – Philippe Jun 25 '16 at 16:20
  • this actually worked, when i set it up in my constructor it always fails for some reason. – FrancoCC Jun 26 '16 at 00:18