Miguel Altamirano Morales Ответов: 1

Изменение структуры в C#


Всем Привет,

В VB Net я использовал Redimstatement для объявления многомерного массива, когда знал, сколько элементов ему нужно. Теперь я работаю с C# и использую элемент управления List<t & gt; типа Struct для выделения той же структуры; я не мог найти, как изменить размер многомерного массива здесь, и моей программе не удобно объявлять его с фиксированным размером.

Теперь мне нужно добавить числовые значения в пару полей структуры, но приложение посылает мне сообщение об ошибке "невозможно изменить возвращаемое значение, потому что это не переменная" или что-то в этом роде (это по-испански).

Возможно ли это сделать?, или вы думаете, что лучше работать с таблицей данных ?

Правильно ли строить свой список из типа структуры, если я хочу этого добиться ?

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

Я думаю, что собираюсь изменить элемент управления List<struct & gt; Для DataTable, и он должен делать то, что я ожидаю (обновлять динамические столбцы), но я не хочу оставаться в сомнениях.

j snooze

Не знаю, понимаю ли я в точности, что вы пытаетесь сделать. Если у вас есть список<t> чего-либо, когда вы определяете его List<t> MyList = new List<t & gt;();.. вы должны быть в состоянии просто сделать MyList.Добавляйте и постоянно добавляйте к нему новые объекты. Разве это не то, что вы пытаетесь сделать?

Miguel Altamirano Morales

Спасибо за ваш комментарий. Да, тот самый .Функция Add работает отлично, то, что я пытаюсь сделать, - это накопить числовое значение во время выполнения. Тип списка - это структура данных, которая содержит поле, которое мне нужно увеличить во время взаимодействия.
Я не знаю, видите ли вы другие ответы, которые я получаю на этот вопрос, но я собираюсь отправить код другому человеку, и я надеюсь, что Вы тоже его увидите. Если вы не можете, пожалуйста, скажите мне, и я пришлю его вам тоже.

1 Ответов

Рейтинг:
7

Dave Kreskowiak

Массивы в C# и VB.NET неизменны. Однажды созданные, они не могут быть изменены. Что делает ReDim в VB.NET это дурачит вас, заставляя думать, что он сделал именно это. Он лгал тебе. На самом деле он создал совершенно новый массив с новым измерением, а затем скопировал содержимое из старого массива в новый, а затем убил старый массив.

Список"T" не имеет такого ограничения, но он делает что-то подобное за кулисами. В список<yourstructtype> есть гораздо лучше, чем объект DataTable. Таблицы данных намного тяжелее, медленнее и используются для представления таблиц базы данных, а не Списка объектов.

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


Miguel Altamirano Morales

Такой интересный ответ, Дэйв, я этого не знал. Большое спасибо.

Вот код:

- Определение:
публичная структура DataColores
{
общественная int id_color;
общественного строка текст;
публичный двойной импорт;
общественного строка nombre_color;
};
публичный статический список & lt;datacolores> TabColores = новый список & lt;datacolores>();

публичная структура DataKolores
{
общественная int id_kolor;
публичная строка ktexto;
публичный двойной кимпорт;
общественные двойной total_grupo;
общественные двойной total_final;
};
публичный статический список<datakolores&ГТ; TabKolores = новый список<datakolores&ГТ;();

- Poblating списки из базы данных Oledb:

OleDbCommand cmdColores = new OleDbCommand ("SELECT * FROM Colores", Cn);

Object[] Datos = новый объект[3]; Oledbdatareader Lector;

cmdColores.Свойство Commandtype = Система.Данных.Свойство commandtype.Текст;
Lector = cmdColores.Метода Executereader (Системы.Данных.Командное поведение.Последовательный процесс);

если (лектор.Read () = = true)
{
делать {
Лектор.GetValues(Datos);
G. TotColores += 1;
G. TabColores.Add (new G. DataColores () {id_color = Convert.ToInt32(Datos[0]), texto = Convert.ToString(Datos[1]), importe = 0, nombre_color = Convert.ToString(Datos[2]) });
TabKolores Г..Add (new G. DataKolores () {id_kolor = Convert.ToInt32(Datos[0]), ktexto = Convert.ToString(Datos[1]), kimporte = 0, total_grupo = 0, total_final = 0 });
}
в то время как (лектор.Read () = = true);
}
Лектор.Закрывать();

Как вы видите, поля с именами "Importe", "kimporte"," total_grupo "и total_final" в структурах, соответствующих спискам, изначально равны нулю, потому что мне нужно накапливать их во время выполнения.

- Когда я пытаюсь добавить числовые значения:

{
Строки Кадена;
for (Ind = 0; Ind <= G. TotColores; Ind++)
{
cadena = G. TabKolores[Ind]. ktexto ;
если (Кадена.Trim () = = G. strKey.Отделка())
{
G. TabKolores[Ind]. kimporte += dblImporte; (//Вот ошибка. В нем говорится, что G. TabKolores[Ind]. kimporte не может быть изменен, потому что он не является переменной. То же самое происходит и в следующих двух строках).
G. TabKolores[Ind]. total_grupo += dblImporte;
G. TabKolores[Ind]. total_final += dblImporte;
перерыв;
}
}
if (Ind > G. TotColores)
Ящик для сообщений.Шоу ("Clave de color no identificada", G. strKey);
}

Раньше я прекрасно справлялся с этим в Visual Basic Net, используя многомерные массивы с Redim во время выполнения, когда программа знает, сколько цветов находится в конкретной таблице, но теперь я пытаюсь сделать то же самое в C#.

Спасибо очень много для вашей помощи.

Dave Kreskowiak

Этот фрагмент кода является неполным и, честно говоря, вообще не имеет смысла. Что такое "г"? Почему вы используете статические переменные в том, что выглядит так, как будто это должен быть экземпляр? Ближе к концу у вас есть ... += dblImporte; несколько раз, но эта переменная нигде не определена и значение нигде не задано.

В принципе, я понятия не имею, что должен делать этот код, но могу сказать вам, что он слишком сложен для того, что он делает.

Кроме того, форматирование кода повсюду, что затрудняет его чтение, понимание и отладку.

Если вы используете "глобальные" переменные, вы совершаете большую ошибку.

Miguel Altamirano Morales

Я послал вам только часть кода, который, как я думал, связан с моей проблемой. Полный код еще не закончен, поэтому в нем много ошибок, потому что я копирую и вставляю его из VB, чтобы исправить его шаг за шагом.
G-это имя статического класса, который я создал для использования глобальных переменных. Мне нужно использовать их в нескольких формах в моем приложении, и это то, что я нашел в интернете, чтобы достичь той же производительности, что и публичные переменные в модуле кода в VB Net, я не знаю, есть ли у C# другой вариант для достижения этой цели.
Переменная dblImporte определяется как numeric-double в другой части кода, доступной для всего модуля,и она приходит со значением для этой процедуры, я не думал, что это необходимо, чтобы отправить вам весь код. И да, я заметил его очень рассеянный вид. Я не знаю, Могу ли я отправить вам текстовый файл.
Что я действительно не хотел бы делать, так это беспокоить вас или причинять вам пустую трату времени, я действительно ценю вашу помощь и могу послать вам все, что вам нужно, но просто если вы хотите продолжать помогать мне, Вы многое сделали для меня до этого момента, и я действительно благодарен вам.

Dave Kreskowiak

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

Класс, в котором он используется, должен поддерживать полный контроль над содержащимися в нем значениями и предоставлять только определенные методы для изменения этих значений.

Каково точное сообщение об ошибке? Это не "это не переменная". Может ли это быть исключение NullReferenceException или "ссылка на объект не установлена на экземпляр объекта"?

Miguel Altamirano Morales

Дать полный доступ к определенным переменным в нескольких (почти всех) формах или модулях моего приложения-это именно то, что мне нужно сделать в этом случае, но если есть лучший способ сделать это, я просто не знаю, как это сделать в C#. Во всяком случае, я прекрасно понимаю, что вы пытаетесь мне сказать.

Может быть, моя проблема в том, что я неправильно объясняю свою цель.

дай мне попробовать:

- Я кодирую на C# приложение, уже разработанное мной в VB Net, которое
отлично работает, только для практики и изучения C#. Я хочу
изучайте C# глубже, а не VB, я уже очень хорошо знаю VB.

- Я использовал многомерные массивы (VB), каждый из которых имел идентификатор цвета[0], имя цвета[1] и 3 накопительных числовых элемента [2,3 и 4], которые должны быть накоплены во время выполнения. Когда я попытался сделать это на C#, то заметил, что это невозможно, и мне просто нужно это сделать.

- Я обнаружил, что больше не могу использовать оператор Redim для многомерного массива, поэтому мне пришлось решить, использовать ли ArrayList, list<t> control или dataTable. Я решил составить список"один".

- Я читал в интернете, что элемент управления List<> ("TabKolores" в моем коде) может быть набран как структура для обработки нескольких полей.

- В том, что тип struct ("DataKolores" в моем коде) мне нужно как минимум 3 поля, которые будут обновлены (sumarized) во время выполнения ("kimporte", "total_grupo" и "total_final" в моем коде).

- Когда я пытаюсь добавить значение, содержащееся в числовой переменной ("dblImporte"), к 3 полям структуры в списке (одно и то же значение), то получаю ошибку"невозможно изменить возвращаемое значение <list>, потому что это не переменная". Сообщение на испанском языке, вот я и пытаюсь перевести его для вас.

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

Спасибо снова.

Dave Kreskowiak

Лучший способ сделать это-создать класс, который содержит необходимую информацию, и передать этот экземпляр класса (объект) по мере необходимости.

Предполагая, что исключение, которое вы получили, было NullReferenceException, вы создали List<datakolores>. The дает вам список< t>, который может содержать кучу datakolores объекты. Он не создавал эти объекты. Итак, вы должны создать экземпляр datakolores и добавьте его в Список для каждого экземпляра, который вы отслеживаете.

Вам придется переделать свой код, чтобы получить что-то более подходящее. Список< t> не имеет понятия, сколько элементов он должен иметь в нем, и у вас нет никакого кода, чтобы указать это:

    public static List<datacolores> TabColores = new List<datacolores>();

    for (int c = 0; c < someMax; c++)
    {
        datacolores newItem = new datacolores();
        newItem.kimporte = 0;  // or init to an appropriate value;
        ...

        TabColores.Add(newItem);
    }

Miguel Altamirano Morales

Это хорошая идея, Дэйв, я собираюсь попробовать что-то подобное и забыть о логике моего предыдущего приложения в VB net, которое я пытался эмулировать. Кроме того, я собираюсь посмотреть, может ли arraylist, содержащий другой arraylist, помочь моим целям.

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

Большое спасибо.

PS: вы знаете парня по имени Кен Такер ?

Dave Kreskowiak

Нет.

Miguel Altamirano Morales

Программа приняла этот код, по крайней мере во время компиляции, я посмотрю, как он работает, когда буду делать свои заключительные тесты (надеюсь, вы сможете его прочитать):

частный недействительными Clasifica_Importe()
{
Строка cadena; Double Kimporte; Double Total_Grupo; Double Total_Final;
for (Ind = 0; Ind <= G. TotColores - 1; Ind++)
{
cadena = G. TabKolores[Ind]. ktexto;
если (Кадена.Trim () = = G. strKey.Отделка())
{
Kimporte = G. TabKolores[Ind]. kimporte;
Total_Grupo = G. TabKolores (Ind]. total_grupo;
Total_Final = G. TabKolores[Ind]. total_final;

Kimporte += dblImporte;
Total_Grupo += dblImporte;
Total_Final += dblImporte;

Г. DataKolores Колорес = Г. TabKolores[Инд];

Колорес.kimporte = Kimporte;
Колорес.total_grupo = Total_Grupo;
Колорес.total_final = Total_Final;
перерыв;
}
}
if (Ind > G. TotColores)
Ящик для сообщений.Шоу ("Clave de color no identificada", G. strKey);
}