Lilith.Cal Ответов: 2

C# соответствующий ментод для хранения общих данных классов


Может быть, я переоцениваю возможности языка. Я работаю над программой для тренировки себя на клавишных музыкальных инструментах с использованием MIDI. Я создал два элемента управления, один из которых представляет клавиатуру, а другой-музыкальные высокие и низкие частоты. Между формой, клавиатурой и персоналом я разработал несколько таблиц преобразования, обычно по одной, но иногда и по две на каждый элемент управления. Некоторые из моих кодов требуют, чтобы один элемент управления получал доступ к таблице из другого. Это быстро стало слишком запутанным для ясности кода или зависимости одного от другого.

Поэтому я решил просто собрать таблицы в один класс и сделать его статичным, чтобы мне не нужно было объявлять его экземпляр. Я начал получать ошибки в коде, и как только я исправил одну вещь, возникла новая проблема. Я пробовал разные механизмы, включая создание общедоступных свойств для доступа к элементам массива. И, возможно, в конце концов у меня появятся словари.

Самая заметная ошибка, которую я получаю, - это при использовании цикла foreach() или for(;;) ошибка, которую я получаю, заключается в том, что требуется экземпляр класса.

Вопросы: Как я должен объявить класс или переменные внутри него? Или, как я должен получить доступ к данным? Или статический класс - это не тот путь, по которому нужно идти?

Что я уже пробовал:

Обратите внимание, что я также пытался объявить массив без конструктора.

namespace Keyboard_Tutor
{
	class MTables {

		private static Note[] _notes;

		public Note this[int i] {
			get => _notes[i];
		}

		static MTables() {
			_notes = new Note[] {
				new Note(1, 21, 0),
				new Note(2, 22, -1),
				new Note(3, 23, 1),
				new Note(4, 24, 2),
				new Note(5, 25, -1),
				new Note(6, 26, 3),
				new Note(7, 27, -1),
				new Note(8, 28, 4),
				new Note(9, 29, 5),
				new Note(10, 30, -1),
				new Note(11, 31, 6),
				new Note(12, 32, -1),

2 Ответов

Рейтинг:
5

Bertha Wwallace

"The most notable error I get is when using either a foreach() or for(;;) loop the error I get is that an instance of the class is required."
-- это понятно, потому что ваш индексатор не является (и не может быть) статичным. Этот 'этот' в
публично обратите внимание на это[int i] это тот экземпляр, который требуется.

Если вы хотите, чтобы класс MTables был статическим, то определите его так:"статический класс MTables".
Массив, к которому вы хотите получить доступ, должен быть статическим методом, например
public static Note GetNote(int i) { return _notes[i]; } 
Тогда вы бы использовали его вот так:
for(int i = 0; i < maxNote; i++)
{
    var note = MTables.GetNote(i); ...
}

Если OTOH вы хотите использовать индексатор этот[] конечно, тогда не делайте класс статичным, но тогда вам придется создать экземпляр, когда вы хотите индексировать его:
var table = new MTables();
for(int i = 0; i < maxNote; i++)
{
    var h = table[i];
}
Вы не можете использовать инструкция foreach если только ваш MTables класс реализует IEnumerable<Примечание> интерфейс, например, как здесь.


Lilith.Cal

Благодарить всех. Я действительно решил эту проблему до ваших ответов, но не смог найти сообщение, чтобы попытаться удалить его. По сути, я обнаружил, что мне нужно сделать почти все статичным. Я все еще расстроен из-за индексации, но.....

У меня также были проблемы с некоторыми из моих кодов ошибок, которые будут возникать во время выполнения. Оказывается, я компилировал в режиме выпуска (чтобы проверить предыдущую проблему) и не мог найти, где находится код, когда он находится в режиме точки останова.

Еще раз спасибо за вашу помощь.

Лил

Рейтинг:
15

Wendelius

Если данные статичны по своей природе, использование статического списка или массива имеет смысл. Если вы получаете ошибки при циклировании списка, мы должны увидеть код, который генерирует ошибку.

Чтобы зациклить заметки, вы, вероятно, хотели бы сделать массив или коллекцию общедоступными, чтобы получить к ним доступ извне этого класса.

Что-то вроде

class MTables {

   public static Note[] Notes;

   static MTables() {
      Notes = new Note[] {
         new Note(1, 21, 0),
         new Note(2, 22, -1),
         new Note(3, 23, 1),
      };
   }
}

И использование
foreach (Note n in MTables.Notes) {
   // do something
}


Bertha Wwallace

Привет Венделиус, в вашем ответе индексатор this[] больше не нужен, вы его не используете. Внешний класс обращается к массиву Notes непосредственно без индексатора... что может быть нежелательно. Конечно, вы всегда можете инкапсулировать частное поле в доступное свойство некоторого полезного типа коллекции.

Wendelius

Хороший момент, я забыл удалить его при копировании исходного кода. Теперь удалить