views:

144

answers:

7

Hi there, I have a struct

struct myStruct {
    Dictionary<string, int> a;
    Dictionary<string, string> b;
    ......
}

I want to create a arraylist of that struct

ArrayList l = new ArrayList();
myStruct s;

s.a.Add("id",1);
s.b.Add("name","Tim");

l.Add(s);

However, I got the error "Object reference not set to an instance of an object."

Anyone could tell me why?

Thanks.

+6  A: 

Since your declaration of dictionary a doesn't instantiate it, you are trying to add an item to a null. This is assuming you marked them public, otherwise that wouldn't compile.

Yuriy Faktorovich
Thanks. But actually I has instantiate them in my code. Still get the same error.
+4  A: 

The problem is that neither a nor b are initiated. Set them to a new dictionary each.

Edit per comment:

Then your problem is elsewhere, as the following works fine:

struct myStruct
{
    public IDictionary<string, int> a;
    public IDictionary<string, string> b;
}

IList<myStruct> l = new List<myStruct>();
myStruct s;

s.a = new Dictionary<string, int>();
s.b = new Dictionary<string, string>();
s.a.Add("id", 1);
s.b.Add("name","Tim");

l.Add(s);
tanascius
Thanks, I added the initiation, but still get the same error
Thanks for the edit @Yuriy .... you get definitely my +1
tanascius
@tanascius, lol clicked on the wrong edit button, I'll leave the change.
Yuriy Faktorovich
@Yuriy: lol, I understand ... thanks anyway! ^^ Next time you get my edit
tanascius
+2  A: 
 struct myStruct {
    private Dictionary<string, int> a;
    private Dictionary<string, string> b;

    public Dictionary<string, int> A
    {
        get { return a ?? (a = new Dictionary<string, int>()); }
    }

    public Dictionary<string, string> B
    {
        get { return b ?? (b = new Dictionary<string, string>()); }
    }
}

This would solve your problem. What you need to do, is to access the dictionaries through the properties (getters).

Karim
+1  A: 

mystruct s is initialized and won't give you a null reference exception. As it initializes, it sets its members to their default values. It therefore sets the a and b members to null since they are reference types.

Erich Mirabal
+4  A: 

Some suggestions to improve your code:

  • Don't use a struct, use a class instead. Structs in .NET are a little different and unless one understands those differences I doubt one will ever have a valid use for structs. A class is almost always what you want.

  • ArrayList is more or less obsolete, it's almost always better to use a generic List<T> instead. Even if you need to place mixed objects in the list, List<object> is a better choice than ArrayList.

  • Make sure your members are properly initialized and not null before you access methods or properties of them.

  • It is better to use properties instead of public fields.

Here is an example:

class Container
{
    Dictionary<string, int> A { get; set; }
    Dictionary<string, string> B { get; set; }

    public Container()
    {
         // initialize the dictionaries so they are not null
         // this can also be done at another place 
         // do it wherever it makes sense
         this.A = new Dictionary<string, int>();
         this.B = new Dictionary<string, string>();
    }
}

...
List<Container> l = new List<Container>();
Container c = new Container();
c.A.Add("id", 1);
c.B.Add("name", "Tim");

l.Add(c);
...
0xA3
These are great suggestions, but I'd perhaps go futher and encapsulate your internal dictionaries with a pair of methods on the `Container` class, say `Add(String key, int value)` and `Add(String key, String value)` which would store those values in the respective `Dictionary` instances. This will help you maintain the class in the long run, since it abstracts the implementation of storage.
codekaizen
A: 

Why are you using an ArrayList these days anyway?

Loren Pechtel
+1  A: 

This might be the problem:

"When you create a struct object using the new operator, it gets created and the appropriate constructor is called. Unlike classes, structs can be instantiated without using the new operator. If you do not use new, the fields will remain unassigned and the object cannot be used until all of the fields are initialized."

Perhaps either you haven't newed up your struct or some of those fields hidden behind the ... are not initialised yet?

http://msdn.microsoft.com/en-us/library/ah19swz4(VS.71).aspx

Lunivore