#c# #arrays #properties
#c# #массивы #свойства
Вопрос:
У меня есть класс, в котором есть 3 общедоступных списка. По сути, это просто класс хранения данных.
У меня есть файл с разделителями, подобными xml (какие-то начальные и конечные теги и промежуточное значение данных)
У меня есть класс parse, который обнаруживает и добавляет определенные объекты в определенные списки из класса хранения данных. По сути, я пытаюсь обнаружить открывающий тег, сохранить его в списке открывающих тегов в моем классе хранения данных.
Способ, которым я пытаюсь пойти (основываясь на плохом оправдании учителей для примера), заключается в том, что Main () создает экземпляр класса хранения данных в объект, аналогично для класса parse . Затем он вызывает ParseMain для анализа файла и разделения тегов, значений данных и закрывающих тегов в их соответствующем списке внутри класса хранения данных. Затем, после завершения работы класса синтаксического анализа, вернувшись в main, я вызываю методы внутри класса данных для отображения данных.
Компилятор в основном кричит на меня, потому что, хотя класс xml data holder был создан в main, он не добавляет или не может добавить в общедоступный список, я получаю конкретно эту ошибку
«Ссылка на объект требуется для нестатического поля, метода или свойства»
Как я могу задать список классов чтения данных из моего класса синтаксического анализа?
Мой учитель привел ужасный пример (у него было все, кроме классов, помеченных как static, и, по сути, он просто поместил код в стиле java / c в пару классов)
Все это дополнительная заслуга для базового класса программирования, в котором я участвую.(обычная версия полностью структурна внутри одного класса)
*** Редактировать — добавление фрагментов кода
XMLDoc XMLData = new XMLDoc();
XMLParse parseXML1 = new XMLParse();
//Calls the parseXML1 method passing it
//the name of the currently opened file.
parseXML1.MainParse(fileIn);
затем к моему основному анализу
public void MainParse(FileStream fileIn)
{
int byteIn;
while ((byteIn = fileIn.ReadByte()) != -1)
{
if (byteIn == '<')
{
ParseElement(ref byteIn,fileIn);
}
ParseElement выглядит следующим образом
public void ParseElement(ref int byteIn,FileStream fileIn)
{
token = byteIn;
//First I need to get the entire tag stored in token
do
{
byteIn = fileIn.ReadByte();
token = byteIn;
} while (byteIn != '>');
token = '>';
//now I insert a / into my compare token
compareToken = token;
compareToken.Insert(1,"/");
//It's an ending tag
if (token == compareToken)
{
//figure this out later
}
//It's an opening tag,store it into element list
else
{
XMLDoc.elements.Add(token);
//also tried XMLData/elements/Add(token)
}
}
и, наконец, мой класс xmlDoc выглядит следующим образом….
class XMLDoc
{
public List<string> elements;
public List<string> dataValues;
public List<string> endingElements;
public XMLDoc()
{
elements = new List<string>();
dataValues = new List<string>();
endingElements = new List<string>();
}
//This method simply displays the contents of the arrays
public void DisplayCollected()
{
Console.WriteLine("Begin unformatted dump");
for (int ii = 0; ii <= elements.Count;ii )
{
Console.WriteLine("n" elements[ii] dataValues[ii]
"n" endingElements[ii]);
}
Console.WriteLine("End unformatted dumpn");
}
//This method will generate an xml style display
//To add later
}
Я играю, учусь на практике и тому подобное. На данный момент мне пришлось отказаться от примера с учителями, как упоминалось выше, он просто сделал каждый метод в каждом классе статичным, вероятно, потому, что он собрал свой пример из основной лабораторной работы (которая структурная и вся внутри первого класса)
Комментарии:
1. Публикация соответствующих частей вашего кода была бы намного эффективнее, чем описание того, как это работает — хотя описание тоже неплохо.
2. Я добавлю сейчас, но это довольно неаккуратно.
3. Неаккуратно или нет, очень сложно ответить с пользой, не видя кода.
Ответ №1:
РЕДАКТИРОВАТЬ: Хорошо, похоже, вам просто нужно передать ссылку на объект, например
XmlDoc xmlData = new XmlDoc();
XmlParser parser = new XmlParser();
parser.MainParse(xmlData, fileIn)
...
public void MainParse(XmlDoc xmlData, FileStream fileIn)
{
...
ParseElement(xmlData, ref byteIn, fileIn);
...
}
public void ParseElement(XmlDoc xmlData, ref int byteIn,FileStream fileIn)
{
...
}
Я немного скорректировал имена, чтобы они были более разумными, IMO.
Кстати, я бы рекомендовал вам не использовать общедоступные поля в XmlDoc
. Общедоступные поля нарушают инкапсуляцию — используйте свойства, если вам действительно нужно просто предоставить значения, но в идеале придать больше поведения самому объекту.
Комментарии:
1. свойства были невозможны с 3 разными списками. Я мог бы использовать свойство, только если бы у меня был 1 список. Я мог бы создать реальный метод для получения и настройки для каждого из них, но на самом деле в конце дня ни один из данных в этой программе на самом деле не нуждается в инкапсуляции (изначально она была написана для лаборатории, все в основном классе, а не ООП) — Мое разочарование заставило меня сказать «к черту, я закончил с этим бороться, это становится общедоступным!» lol — Большое вам спасибо за помощь
2. @Tyler: Почему у вас не может быть трех разных свойств?
3. @Tyler, вы, кажется, что-то неправильно поняли в моем предыдущем ответе. Вы можете не использовать свойства только для списков, если хотите иметь возможность контролировать, что входит в список . Если вы рады, что клиенты вашего класса могут добавлять / удалять элементы в / из списков (или полностью заменять списки, тогда свойства в порядке. Если вы хотите иметь возможность проверять элементы перед их добавлением или выполнять какую-либо другую логику при добавлении / удалении / изменении чего-либо, вы не можете предоставлять списки публично, ни в виде полей, ни через свойства. PS вам следует начать принимать некоторые ответы на некоторые из ваших вопросов
4. насколько я понимаю, я не могу фактически использовать свойства (get; set;) с массивами или списками <string> из-за того, как определены индексаторы. такие, что, скажем, list<string> a; и list<string> b; находятся в одном классе, но свойство для массивов и списков будет общедоступным list<string> this[ii] {get;set;} —
5. @Tyler: Нет, свойства вполне возможно использовать с массивами и списками. Никто не говорит, что вы должны использовать индексатор — вы можете написать свойство, которое возвращает список.
Ответ №2:
Сообщение об ошибке здесь довольно хорошее: «Ссылка на объект требуется для нестатического поля, метода или свойства»
Вы пытаетесь вызвать метод экземпляра статическим способом, у вас есть два варианта:
- Сделайте метод статическим.
- Создайте экземпляр класса и вызовите метод из экземпляра.
Например:
public class Foo()
{
public void Frob() {}
}
Вы не можете этого сделать:
Foo.Frob();
Но вы можете сделать это:
var foo = new Foo();
foo.Frob();
или это:
public class Foo()
{
public static void Frob() {} // Note static
}
[...]
Foo.Frob();