0

Недавно начал кодить на c# и наткнулся на одно "магическое" исключение System.NullReferenceException: "В экземпляре объекта не задана ссылка на объект." Пытался найти в гугле о ссылках и вроде нашёл, но так ничего не понял.

Надеюсь вы мне поможете разобраться с этой чёрной магией

Вот код (обновлено):

using System;
using System.Collections.Generic;

namespace ConsoleTest { class Program { public static string[] add; static void Main(string[] args) { while (true) { Console.Write("> "); var str = Console.ReadLine();

            Console.WriteLine();
            var arg = str.Split(' ');
            if (arg[0] == "set")
            {
                add[Int32.Parse(arg[1])] = arg[2];
                Console.WriteLine("Added {0} => {1}", arg[1], arg[2]);
            }
            else if (arg[0] == "get")
            {
                Console.WriteLine("Returned {0} => {1}", arg[1], add[Int32.Parse(arg[1])]);
            }


        }
    }
}

}

(Слишком много правок XD)

Выдаёт ошибку на строке add[Int32.Parse(arg[1])] = arg[2];

Чуть подробнее

После запуска я пишу add 5 test потом Enter и вылезает ошибка.

По замыслу должно сделаться это (естественно ошибка не была в планах): add[5] = "test";

Строкой add[Int32.Parse(arg[1])] = arg[2]; я пытаюсь добавить в массив add значение arg[2] с индексом arg[1] (+ преобразование строки в число).

Массив arg это полученная строка через Console.ReadLine() и разбитая с помощью .Split(' ')

Массив add объявлен: public static string[] add;

Я путался добавлять пустые элементы так:

whlie(add[Int32.Parse(arg[1])] == null) { add.Add(""); }

но это не помогло.

Суть проблемы

Я не знаю конечного кол-ва мест для содержимого, т.к. это id сессии, номер которой может быть непредсказуемым.

И так, господа

Сегодня я вам всем изрядно напряг мозги, я благодарю вас за терпение.

Спасибо всем за советы, но до решения я дошёл сам

Т.к. я не нашёл кнопку ответа, то ответ тут

public static void _add(int key, string val) {
    if (key >= add.Length) { Array.Resize(ref add, key + 1); }
    add[key] = val;
    foreach (var item in add)
    {
        Console.WriteLine(item);
    }
}

Я добавил эту функцию и когда надо записать что-то в массив add я писал _add(index, value) и всё стало хорошо.

Теперь главное чтобы mono смог скомпилировать сие чудо (mcs на linux)

  • Не совсем. Там отношения между классами а у меня функция не видит переменную, которая лежит в этом же классе – Дмитрий Jun 14 '17 at 17:04
  • отсутствует значение – code211218 Jun 14 '17 at 17:05
  • Может, Вы добавите объяснение того, что этот код пытается делать, и с какими параметрами Вы его вызываете? А вообще-то, add нигде не назначается и остаётся с дефолтным значением null. –  Jun 14 '17 at 17:19
  • что ты хочешь этим сделать ? add[Int32.Parse(arg[1])] = arg[2]; – code211218 Jun 14 '17 at 17:51
  • Здесь вы public static string[] add; объявляете переменную, но не создаете массив, а здесь add[Int32.Parse(arg[1])] = arg[2]; пытаетесь писать в массив, но он же еще не был создан?! – Bulson Jun 14 '17 at 23:13
  • @Дмитрий Массив add НЕ СОЗДАН: public static string[] add;, а объявлен - "почувствуйте разницу". –  Jun 15 '17 at 14:52
  • @Igor Не чувствую. Что тогда есть создан? – Дмитрий Jun 15 '17 at 14:57
  • @Дмитрий add = new string[123]; - создает массив строк, в котором есть места для 123-х элементов. А public static string[] add; - говорит, что в классе есть статическое поле, которое может указывать на массив строк, какой-нубудь длины, а может никуда не указывать (null) - что является его начальным состоянием. –  Jun 15 '17 at 14:57
  • @Igor А что делать если я не знаю длину массив (сколько мест надо) ибо она динамичная. Я нашёл в документации .Resize но проблема в том, что это только для .NET 4.5 – Дмитрий Jun 15 '17 at 15:05
  • @Дмитрий Надо создавать массив в тот момент, когда его длина станет известна. Но я так и не понял, зачем Вам этот массив. Может быть вместо него подойдет Dictionary<string, string>. –  Jun 15 '17 at 15:15
  • @Igor Этот массив просто для теста записи. Но т.к. я не хотел засорять тестами код с сокетами (сервер), то запихнул тест сюда (это давно забытое мной консольное приложение с системой "функций"). | Смысл был таков, что один юзер записывает в серверную переменную что-то с id своей сессии, а другой получает по id сессии это содержимое. А за совет спасибо, сейчас попробую – Дмитрий Jun 15 '17 at 15:37
  • @Дмитрий естественно, при выполнении условия if (key >= add.Length) Вы не присваиваете значение. –  Jun 15 '17 at 17:01
  • Господа,а как на свой ответить? XD – Дмитрий Jun 15 '17 at 17:06
  • @Дмитрий на этот вопрос Вы в данный момент не можете ответить, потому что он закрыт, как дубликат –  Jun 15 '17 at 17:55

1 Answers1

1
else if (arg[0] == "add" && arg.Count() >= 2)
{
    switch (arg[1])
    {
        case ("test"):
            add = new string[] { "test_val" };
            //add[0] = "test_val";
            Console.WriteLine("Added test_key => test_val");
            break;
        default:
            //здесь не понятно что ты хочешь сделать?
            if (arg.Count() >= 3 && Int32.Parse(arg[1])>=0)
            {
                var a = Int32.Parse(arg[1]);
                add = new string[a + 1];
                add[Int32.Parse(arg[1])] = arg[2];
                Console.WriteLine("Added {0} => {1}", arg[1], arg[2]);
            }arg[2]);
            break;
    }
}
else if (arg[0] == "get" && arg.Count() >= 2)
{
    Console.WriteLine("Returned {0} => {1}", arg[1], add[Int32.Parse(arg[1])]);
}
Sv__t
  • 2,713
code211218
  • 3,953