Не выходит получить значение словаря по ключу из метода другого класса
Нужно обратится из класса Print к полю XmlData класса Program, которое является словарём.
Я знаю, что могу обратится к существующему полю используя оператор квадратные скобки. Например, wiwsId = XmlData[WiwId]
Однако, когда я из класса Print обращаюсь к Program.XmlData[A], то получаю ошибку Compiler Error CS0103: Имя "A" не существует в текущем контексте.
Код:
using System.Collections.Generic;
class Program {
static readonly string A;
static readonly string B;
public static Dictionary<string, string> Data = new(2)
{
{ A, "TestA" },
{ B, "TestB" }
};
}
class Print {
static void PrintConsole(string[] args) {
Console.WriteLine(Program.Data[A]);
}
}
Ответы (1 шт):
Словарь в C# ( Dictionary<TKey, TValue> ) - это объект, который хранит в себе ключи и их значения. Ключ, как и значение, представляет собой экземпляр некоторого класса, в вашем случае, и то, и то - строки.
Поиск значения в словаре работает примерно так:
- Вы передаёте в квадратных скобках объект-ключ
- Словарь, используя заданный сравниватель (
Comparer<T>), ищет первый попавшийся объект-ключ, который будет равнятся тому объекту-ключу, что вы передали в квадратных скобках. По умолчанию равными считаются те объекты, у которых совподают их хеши (хеш можно получить для любого объекта так:obj.GetHashCode()). - После совпадения ключа, словарь берёт то значение, к которому "привязан" ключ, и возращает его вам. Если объект-ключ не совпал ни с одним из тех, что есть в словаре, вы увидите исключение
Зная эту информацию переосмыслим ваш код (который надо прикладывать сразу!!!).
Вы в классе Program сходу определили две строки:
static readonly string A;
static readonly string B;
Строки в C# хранят в себе текст. Их название никак не влияет на то, какой текст в них лежит. Так как вы не присвоили строкам никакой текст, по умолчанию строки стали равны null.
После этого вы создаёте словарь:
public static Dictionary<string, string> Data = new(2)
{
{ A, "TestA" },
{ B, "TestB" }
};
Это абсолютно тоже самое, что если бы вы написали так:
public static Dictionary<string, string> Data = new()
{
{ null, "TestA" },
{ null, "TestB" }
};
Это, очевидно, является абсурдом и выдаст вам исключение времени исполнения (Runtime Error), так как словарь не позволяет ключам равнятся null.
Теперь разберёмся с ошибкой компиляции (Compile Error), описанной в вопросе, в этой строке кода:
Console.WriteLine(Program.Data[A]); // Compiler Error CS0103
Если прочесть описание ошибки, которое вы не приложили (но его всёравно можно найти по коду на MSDN), то можно узнать, что причина ошибки в том, что поле, которое вы хотите передать в квадратных скобках
не существует в текущем контексте
Когда вы пишите имя переменной, поля или свойства или чего угодно ещё, компилятор пытается это "что-то" найти в коде в определённых рамках. Когда вы пишите A, то (опустим многие вещи и другие случаи) компилятор смотрит: нет ли в текущем классе поля, свойства или переменной с именем A. Такого, как мы можем понять, нет, по-этому появляется ошибка.
Чтобы обратится к вашему статическому полю надо написать так:
Console.WriteLine(Program.Data[Program.A]);
Так компилятор поймёт, что вы имеете ввиду поле A класса Program.
В итоге рабочий код может выглядеть так:
using System.Collections.Generic;
class Program
{
static readonly string A = "Key1";
static readonly string B = "Key2";
public static Dictionary<string, string> Data = new()
{
{ A, "TestA" },
{ B, "TestB" }
};
}
class Print
{
static void PrintConsole(string[] args) {
Console.WriteLine(Program.Data[Program.A]);
}
}
Или же можно вообще обойтись без этих полей:
using System.Collections.Generic;
class Program
{
public static Dictionary<string, string> Data = new()
{
{ "Key1", "TestA" },
{ "Key2", "TestB" }
};
}
class Print
{
static void PrintConsole(string[] args) {
Console.WriteLine(Program.Data["Key1"]);
}
}