none
KeyNotFoundException: The given key was not present in the dictionary Hatası Alıyorum neden RRS feed

  • Soru

  • KeyNotFoundException: The given key was not present in the dictionary.
    System.Collections.Generic.Dictionary`2[System.String,System.Object].get_Item (System.String key) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Collections.Generic/Dictionary.cs:150)
    load.Start () (at Assets/script/load.cs:22)

    ///////////////////////////////////////////////////////////////////

    Load Kodları.

    using UnityEngine;
    using System.Collections;
    using System.Runtime.Serialization.Formatters.Binary;
    using System.IO;
    using System.Collections.Generic;

    public class load : MonoBehaviour {

    // Use this for initialization
    void Start () {
            var bf = new BinaryFormatter();
            var fileName = Path.Combine(Application.persistentDataPath, "PlayerInfo.dat");
            var ms = new MemoryStream(File.ReadAllBytes(fileName));
            var loadedData = (Dictionary<string, object>)bf.Deserialize(ms);

            GlobalVariables.PlayerGameData.Et = (float)loadedData["Et"];
            GlobalVariables.PlayerGameData.Odun = (float)loadedData["Ağaç"];
            GlobalVariables.PlayerGameData.Tas = (float)loadedData["Taş"];
            GlobalVariables.PlayerGameData.Para = (float)loadedData["Para"];
            GlobalVariables.PlayerGameData.AvlanmaBecerisi = (float)loadedData["AvlanmaBecerisi"];
            GlobalVariables.PlayerGameData.Agackesmebecerisi = (float)loadedData["AgacKesmeBecerisi"];
            GlobalVariables.PlayerGameData.Tascıkarmabecerisi = (float)loadedData["TasKirmaBecerisi"];
            GlobalVariables.PlayerGameData.Madencıkarmabecerisi = (float)loadedData["MadenKazmaBecerisi"];
            GlobalVariables.PlayerGameData.Marangoz = (bool)loadedData["MarangozAktif"];

        }

    // Update is called once per frame
    void Update () {

    }
    }

    ///////////////////////////////////////////

    Save Kodları.

    using UnityEngine;
    using System.Collections;
    using System.Runtime.Serialization.Formatters.Binary;
    using System.IO;
    using System.Collections.Generic;

    public class save : MonoBehaviour {

    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {
            var bf = new BinaryFormatter();
            var fileName = Path.Combine(Application.persistentDataPath, "PlayerInfo.dat");
            var ms = new MemoryStream();

            var saveData = new Dictionary<string, object>();
            saveData.Add("Et", GlobalVariables.PlayerGameData.Et);
            saveData.Add("Ağaç", GlobalVariables.PlayerGameData.Odun);
            saveData.Add("Taş", GlobalVariables.PlayerGameData.Tas);
            saveData.Add("Para", GlobalVariables.PlayerGameData.Para);
            saveData.Add("AvlanmaBecerisi", GlobalVariables.PlayerGameData.AvlanmaBecerisi);
            saveData.Add("AgacKesmeBecerisi", GlobalVariables.PlayerGameData.Agackesmebecerisi);
            saveData.Add("TaskirmaBecerisi", GlobalVariables.PlayerGameData.Tascıkarmabecerisi);
            saveData.Add("MadenKazmaBecerisi", GlobalVariables.PlayerGameData.Madencıkarmabecerisi);
            saveData.Add("MarangozAktif", GlobalVariables.PlayerGameData.Marangoz);
            bf.Serialize(ms, saveData);
            File.WriteAllBytes(fileName, ms.ToArray());
        }

    }
    [System.Serializable]
    class saveData
    {
        public float Et;
        public float Ağaç;
        public float Taş;
        public float Para;
        public float AvlanmaBecerisi;
        public float AgacKesmeBecerisi;
        public float TaskirmaBecerisi;
        public float MadenKazmaBecerisi;
        public bool MarangozAktif;

    }

    18 Ağustos 2016 Perşembe 21:11

Tüm Yanıtlar

  • Ne yazik ki, string kullanmanin dertlerinden birisi bu, dogru yazip yazmadiginizi ancak calistirinca anliyorsunuz. Madem binary formatta saklayacaktiniz, keske araya hic Dictionary sokmadan class ya da struct saklasaydiniz, o zaman bu hatayi yapmazdiniz. Hata olmayan bir key kullanmanizda (mesajda yazmis zaten):

    GlobalVariables.PlayerGameData.Tascıkarmabecerisi = (float)loadedData["TasKirmaBecerisi"];

    boyle bir key yok sakladiginizda:

    saveData.Add("TaskirmaBecerisi", GlobalVariables.PlayerGameData.Tascıkarmabecerisi;
    yani TasKirmaBecerisi degil TaskirmaBecerisi olacakti.

    18 Ağustos 2016 Perşembe 22:26
  • Hocam en başta class idi, ama arkadaş oyunda update yapmak istiyordu ve classa field eklenme ihtimali vardı, bu durumda eski sürüme ait dosya deserialize olamayacaktı hata verecekti. Oyuncunun save bilgileri kaybolacaktı. Bende o zaman Dictionary yaptırdım. 

    Ama her frame de dosyaya kaydetmemesi gerektiğini bir türlü anlatamadım, inat ediyor. Yukardaki Update methodu saniyede 100-150 defa çalışıyor. :)

    Ayrıca dedim ki, değişken/key isimlerini ya tam İngilizce ya da tam Türkçe kullan, karışık kullanma, kolaylık olur, az hata yaparsın dedim ama ona da inat ediyor. 


    e-mail: onay[nokta]yalciner[at]hotmail[nokta]com





    19 Ağustos 2016 Cuma 06:24
  • Anladim. Gercek hayatta ben benzer bir duruma dustum, hata olmasin diye dictionary keyler icin kendime bir const readonly serisi yarattim (neden enum degil dersen, tip cevirimleri ile ugrasmak istemedim, boyle aradaki fark belli olmuyor zaten :)

    public class ConfigItems
    {
            public const int REC_GEN_MSG = 1;
            public const int REC_NEW_USERS = 2;
            public const int REC_LONG_WARN = 3;
    // ...
    }
    
    //...
    {
       private Dictionary<int, Config> config;
    // ...
     
       config = ctx.Config.ToDictionary(cfg => cfg.REC_ID);
    // ...
    }
    
    // ..
    {
    // ...
       var msg = config[ConfigItems.REC_GEN_MSG].Rec_Val;
    // ...
    }

    19 Ağustos 2016 Cuma 08:44