0

I don't have any problem when I tried to get the keys, but I was having a problem when I tried to get the value from a Dictionary. The values is a class that contains 2 fields with a constructor with 2 parameters. Here is the code :

    public class SetupWeapon {

        public int poolSize;
        public GameObject prefab;

        public SetupWeapon(int size, GameObject goPrefab) {
            this.poolSize = size;
            this.prefab = goPrefab;
        }
    }
    private SetupWeapon[] _setupWeapon = new SetupWeapon[1];
    private Dictionary<int, SetupWeapon> _weaponData = new Dictionary<int, SetupWeapon>();
    public int[] AttackIDs {
        get {
            var toArray = _weaponData.Select(a => a.Key).ToArray();
            return toArray;
        }
    }
    private int[] PoolSize {
        get {
            var toArray = _weaponData.Select(a => a.Value.poolSize).ToArray();
            return toArray;
        }
    }
    private GameObject[] Prefab {
        get {
            var toArray = _weaponData.Select(a => a.Value.prefab).ToArray();
            return toArray;
        }
    }

    void Start () {
        CollectData(setPhysical); // collecting data
        CollectData(setLeftEye);
        CollectData(setRightEye);
        CollectData(setForehead);
        CollectData(setMouth);
        for (int i = 0; i < AttackIDs.Length; i++){
            Debug.Log(AttackIDs[i]); // works just fine
            Debug.Log(_weaponData[0].poolSize); // works just fine
            Debug.Log(_weaponData[0].prefab.name); // works just fine
            Debug.Log(PoolSize[0]); // NullReferenceException
            Debug.Log(Prefab[0].name); // NullReferenceException
        }
    }

Did I miss something important that cause this error ?

Ali Akbar
  • 39
  • 10
  • Possible duplicate of [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) – rene Jul 01 '17 at 01:10
  • I don't think that thread solved my problem. In my case it's just the values part that give me NullReferenceException. And don't you think this lines of code is weird ? `Debug.Log(_weaponData[0].poolSize); // works just fine Debug.Log(_weaponData[0].prefab.name); // works just fine Debug.Log(PoolSize[0]); // NullReferenceException Debug.Log(Prefab[0].name); // NullReferenceException` – Ali Akbar Jul 01 '17 at 01:23
  • 1
    It seem you've not initialized the dictionary _weaponData. It has been created, but not added any element – Trung Duong Jul 01 '17 at 01:26
  • You mean like this ? `private Dictionary _weaponData = new Dictionary() { { 0, new SetupWeapon(0, new GameObject()) } };` No. It's not used to be like that. – Ali Akbar Jul 01 '17 at 01:34
  • Please read my `Debug.Log` code inside the Start method. You can see that `Debug.Log(_weaponData[0].poolSize);` **works just fine** while this one `Debug.Log(PoolSize[0]);` got **NullReferenceException** – Ali Akbar Jul 01 '17 at 01:38
  • 2
    Obviously one of the values added to the dictionary is null and hence causing NRE during enumeration. Unfortunately it is very hard to say where exactly it is coming from as post does not have [MCVE]. You may also want to add exact call stack so it is clear that NRE happens as part of `ToArray()` call (otherwise people makes totally random guesses). – Alexei Levenkov Jul 01 '17 at 02:52

2 Answers2

0

I copied your class and created some test code in dotnetfiddle.

https://dotnetfiddle.net/Widget/Ohctbm

I'm able to get the null exception if a null SetupWeapon has been added to your _weaponData

Btw, when you access _weaponData[0] , you use 0 as key, when you access PoolSize[0], 0 should be index. Not sure if you intend to do this.

public class Program
{
    public class GameObject{
        public string name;
    }

   public class SetupWeapon {

        public int poolSize;
        public GameObject prefab;

        public SetupWeapon(int size, GameObject goPrefab) {
            this.poolSize = size;
            this.prefab = goPrefab;
        }
    }


        public int[] AttackIDs {
        get {
            var toArray = _weaponData.Select(a => a.Key).ToArray();
            return toArray;
        }
    }
    private int[] PoolSize {
        get {
            var toArray = _weaponData.Select(a => a.Value.poolSize).ToArray();
            return toArray;
        }
    }
    private GameObject[] Prefab {
        get {
            var toArray = _weaponData.Select(a => a.Value.prefab).ToArray();
            return toArray;
        }
    }

    public Dictionary<int, SetupWeapon> _weaponData = new Dictionary<int, SetupWeapon>();
    public void Start () {

        for (int i = 0; i < AttackIDs.Length; i++){
            Console.WriteLine(AttackIDs[i]); // works just fine
            Console.WriteLine(_weaponData[0].poolSize); // works just fine
            Console.WriteLine(_weaponData[0].prefab.name); // works just fine
            Console.WriteLine(PoolSize[0]); // NullReferenceException
            Console.WriteLine(Prefab[0].name); // NullReferenceException
        }
    }

    public static void Main()
    {
        var p = new Program();
        p._weaponData.Add(0, new SetupWeapon(0, new GameObject(){ name = "0"}));
        p._weaponData.Add(1, null);  // this will cause null exception
        p._weaponData.Add(2, new SetupWeapon(2, null)); // this will not cause null exception

        p.Start();

    }
}
Huan Jiang
  • 247
  • 4
  • 13
  • I have a method that have multi purpose. The values in the dictionary sometimes have to be null and it seems I was confused with that. So maybe I have to rewrite the methods to make it more easy to read. Thanks for your help sir. – Ali Akbar Jul 01 '17 at 04:35
0

You can only Get SetupWeapon[] instead of GameObject[].

bo hua
  • 1
  • 1