Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

NullReferenceException, but where and what?

Discussion in 'Scripting' started by qdmvw0tc, Jun 18, 2020.

  1. qdmvw0tc

    qdmvw0tc

    Joined:
    May 25, 2020
    Posts:
    3
    Code (CSharp):
    1. NullReferenceException: Object reference not set to an instance of an object
    2. Yolk.ExampleYolk+<Listener>d__1.MoveNext () (at <2dabf455fda34e628ddf8ba00815aa7c>:0)
    3. UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at <58a34b0a618d424bb5fc18bb9bcdac20>:0)
    4.  
    This is the entire code:
    Code (CSharp):
    1. namespace Yolk
    2. {
    3.  
    4.     public class ExampleYolk : MonoBehaviour
    5.     {
    6.  
    7.         public void Start() => StartCoroutine(Listener());
    8.  
    9.         public IEnumerator Listener()
    10.         {
    11.             while (true)
    12.             {
    13.                 if (Input.GetKeyDown(KeyCode.Q))
    14.                     yep["55"]["111"]["55"] = "uu rr";
    15.                     // It has to be this line
    16.                
    17.                 yield return null;
    18.             }
    19.         }
    20.        
    21.        
    22.         [DefinitelyTarget]
    23.         public Dictionary<string, Dictionary<string, Dictionary<string, string>>> yep { get; set; } = default;
    24.        
    25.     }
    26. }
    I need that
    get; set;
    for certain reasons. It does not mention what is missing. It doesn't even mention the line, I had to guess and strip the code. Removing
    [DefinitelyTarget]
    doesn't change anything.
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,971
    Where you do you initialize
    yep
    ? I'm not talking about setting it to
    default
    ... default is null. That's your error.

    You have to initialize
    yep
    , then initialize each layer going in, like an onion, and obviously do it for each key at each layer, because there are dictionaries within dictionaries. Obviously you must check the layer for null before initializing them, otherwise you'll wipe out previously-stored values.

    Are you just looking for some construct that maps three arbitrary strings to another string?? Because you can do that with a custom keying function, perhaps one that concatenates the key strings and uses that to look up in a
    Dictionary<string,string>
    . Or do you really need a nested dictionary of dictionaries of dictionaries of strings? I can't imagine your use case.
     
    qdmvw0tc and PraetorBlue like this.
  3. qdmvw0tc

    qdmvw0tc

    Joined:
    May 25, 2020
    Posts:
    3
    Code (CSharp):
    1. public Dictionary<string, Dictionary<string, Dictionary<string, string>>> yep { get; set; } = new Dictionary<string, Dictionary<string, Dictionary<string, string>>>();
    Doesn't work either, is that what you meant?
    Code (CSharp):
    1. KeyNotFoundException: The given key was not present in the dictionary.
    2. System.Collections.Generic.Dictionary`2[TKey,TValue].get_Item (TKey key) (at <437ba245d8404784b9fbab9b439ac908>:0)
    3. Yolk.ExampleYolk+<Listener>d__1.MoveNext () (at <e7228ae2785b4edda10cff01bc4b9b63>:0)
    4. UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at <58a34b0a618d424bb5fc18bb9bcdac20>:0)
    5.  
    I'm trying to stress test a certain script, this was just a test case, but it threw instead, even when I deleted the library. I thought that creating a Dictionary wouldn't be an issue, so this is why I'm posting. I'm interested in why its failing. It might be knowledge more useful in the future. As for now its beyond me why its failing, and I need to know because Dictionaries are pretty basic structures, I can't go more advanced if I fail something so basic.

    Edit:
    Code (CSharp):
    1. yep = new Dictionary<string, Dictionary<string, Dictionary<string, string>>>()
    2.                     {
    3.                         ["one"] = new Dictionary<string, Dictionary<string, string>>()
    4.                         {
    5.                             ["two"] = new Dictionary<string, string>()
    6.                             {
    7.                                 ["three"] = "four"
    8.                             }
    9.                         }
    10.                     };
    Does work. But why doesn't the first example?

    Edit 2:
    I see. I literally have go on, one by one create Dictionaries to be able to assign data to them. I hoped .NET created Dictionaries automatically upon assignment.
     
    Last edited: Jun 18, 2020
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,971
    Well they gotta exist before you can use 'em! Pretty much 100% of all reference types work this way in C#.

    If you need it cleaner, wrap it up in some kind of helper function.
     
    qdmvw0tc likes this.