1

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.

codekaizen
  • 26,990
  • 7
  • 84
  • 140
Mavershang
  • 1,266
  • 2
  • 15
  • 27
  • 1
    On what line do you get the error? – SWeko Jul 01 '10 at 21:18
  • 2
    Tip: Don't use an ArrayList for collections of structs. Doing so requires that the structs are boxed into objects, which just uses more resources and is unnecessary. Use a `System.Collections.Generic.List` instead. – Mark H Jul 01 '10 at 21:18

6 Answers6

6

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
  • 67,283
  • 14
  • 105
  • 142
5

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);
...
Community
  • 1
  • 1
Dirk Vollmar
  • 172,527
  • 53
  • 255
  • 316
  • 1
    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 Jul 01 '10 at 21:39
4

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);
Jesse C. Slicer
  • 19,901
  • 3
  • 68
  • 87
tanascius
  • 53,078
  • 22
  • 114
  • 136
2
 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 Agha
  • 3,606
  • 4
  • 32
  • 48
1

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
  • 9,860
  • 3
  • 34
  • 39
1

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
  • 17,277
  • 4
  • 47
  • 92