Я все еще не могу до конца понять, что вы пытаетесь сделать. Но я сделаю все возможное, чтобы показать тебе кое-что.
Я беру это предложение, которое вы написали: "Конечная цель этого-раскрыть этот словарь и разрешить различным методам напрямую читать/записывать из/в него". В качестве моего руководства.
Неполные Проблемы с Классами
Как я уже упоминал в комментариях: не существует такого понятия, как Частичный класс. Ключевое слово partial просто указывает, что класс может быть определен более чем в одном файле. Правила определения класса остаются прежними, просто некоторые члены класса могут быть определены в одном файле, а другие части-в других файлах.
Проблемы, с которыми вы здесь сталкиваетесь, не имеют ничего общего с partial
ключевое слово.
Ваши двое // Это не работает Примечания
Первый выглядит так:
partial class ClassA
{
ExampleDictionary instanceOfDict = new ExampleDictionary();
instanceOfDict.Add(1, "Test1"); // This does not work
//other code
}
В первой строке объявляется поле закрытого участника ClassA
названный instanceOfDict
и инициализирует его. Вот почему он компилируется.
Вторая строка пытается поместить выполняемый код (вызов функции) непосредственно в область верхнего уровня класса. Ты не можешь этого сделать. Вы можете поместить кучу вещей в область верхнего уровня класса (например, поля, свойства, методы, делегаты, перечисления, внутренние классы), но вы не можете поместить туда код.
Ваша вторая проблема выглядит так:
public static void FunctionA()
{
for (int i = 0; i < 10; i++)
{
string text = $"Test{i}";
instanceOfDict.Add(i, text); // This does not work as well
}
}
Функция-это static
метод. instanceOfDict
является закрытым полем класса, не объявленным как статическое. Вы не можете ссылаться на экземпляр на элементы уровня экземпляра (методы, свойства, поля,...) из статического метода. Прочитайте о static
ключевое слово.
Создание класса, который выборочно предоставляет словарь
Поскольку вы хотите выполнить некоторую работу со словарем внутри класса, но выставить его снаружи, я пошел на все и сделал свой класс универсальным на <TKey, TValue>
так что он работает со словарями любого типа.
Я также заставил его реализовать шаблон инициализации коллекции, чтобы вы могли инициализировать экземпляры своего класса так же, как это был словарь.
Чтобы использовать шаблон инициализации коллекции, ваш класс должен выполнять определенные действия:
Осуществлять IEnumerable
или IEnumerable<T>
(T
может быть любого типа, а не только того, который вы собираете - вы даже можете просто бросить NotImplementedException
если тебе все равно)
Включите метод, который выглядит следующим образом public void Add (SomeType atLeastOneParameter)
. У вас может быть более одной перегрузки Add
если ты хочешь.
Итак, я начинаю с этого (обратите внимание, что он реализует IEnumerable<T>
:
public partial class TestExposedDictionary<TKey, TValue> : IEnumerable<TValue>
{
private readonly Dictionary<TKey, TValue> _theDictionary = new Dictionary<TKey, TValue>();
public void Add(TKey key, TValue value)
{
_theDictionary.Add(key, value);
}
public IEnumerator<TValue> GetEnumerator()
{
foreach (var kvp in _theDictionary)
{
yield return kvp.Value;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
Этого достаточно, чтобы класс в основном выглядел как словарь (вы, вероятно, хотите добавить какой-то способ получения данных и т. Д. Но это зависит от вас (вы, вероятно, хотите иметь индексатор (на TKey
) и а TryGetValue
.
Но давайте добавим в класс еще несколько случайных функций (поместите это в область верхнего уровня класса).:
public int Count => _theDictionary.Count;
public IEnumerable<KeyValuePair<TKey, TValue>> GetKeyValuePairs()
{
foreach (var kvp in _theDictionary)
{
yield return kvp;
}
}
Это позволит вам увидеть, сколько вещей есть в вашем словаре, и позволит вам перебирать элементы (в KeyValuePairs
) что Словарные коллекции. Не стесняйтесь добавлять дополнительные функции.
Наконец, чтобы проверить это...
public static void Test()
{
var testDict = new TestExposedDictionary<int, string> {
{1, "one" },
{5, "five" },
{8, "eight" },
{10, "ten" },
{105, "hundredFive" },
};
// I can call Add in the normal way as well:
testDict.Add(300, "threeHundred");
Console.WriteLine($"TestDict Count: {testDict.Count}");
foreach (string s in testDict)
{
Console.WriteLine(s);
}
}
Когда я запускаю этот код, я получаю:
TestDict Count: 6
one
five
eight
ten
hundredFive
threeHundred
Разделение этого с помощью частичного
Я не знаю, почему вы хотите использовать partial class
. Обычно это делается для того, чтобы иметь два фрагмента кода, которые редактируются/поддерживаются разными персонажами (типичная причина заключается в том, что механизм шаблонов/волшебства Visual Studio поддерживает одну сторону partial class
а программист другой.
Правила довольно просты, вы просто заявляете public partial class MyClass
в двух файлах. Два файла должны находиться в одном проекте (т. Е. скомпилированы в одну сборку), а классы должны находиться в одном пространстве имен. Как только вы это сделаете, просто разделите (область верхнего уровня) по частям на два partial class
заявления.
В этом случае я бы, вероятно, разделил его таким образом:
- С одной стороны, я бы поставил две функции, необходимые для реализации объявленного
IEnumerator<TValue>
:
public IEnumerator<TValue> GetEnumerator()
IEnumerator IEnumerable.GetEnumerator()
- С другой стороны, я бы поставил все остальное:
- Объявление и инициализация словаря
- Другой перечислитель:
public IEnumerable<KeyValuePair<TKey, TValue>> GetKeyValuePairs()
public int Count => _theDictionary.Count;
public void Add(TKey key, TValue value)