Click here to Skip to main content
15,560,045 members
Please Sign up or sign in to vote.
1.00/5 (2 votes)
See more:
Hi Everybody,

In VB Net I used to use ´Redim´statement to declare a multidimentional array, when I did know how many elements it needed. Now I´m working with C# and I am using a List<t> control of type Struct to allocate the same structure; I couldn´t find how to resize a multidimentional array here and it is not convenient to my program to declare it with a fixed size.

Now, I have to add numeric values to a couple of the fields in the structure, but the app sends me a error message "it is not posible to change the return value, because is not a variable" or something like that (it´s in spanish).

Is it posible to do this ?, or do you think it should be better to work with a Data Table ?

Is it correct to built my List from a Struct Type, if I want to acieve this ?

What I have tried:

I think I am going to change the List<struct> control for a DataTable, and it should do what I expect (update colums dinamycally), but I don´t want to stay in doubt.
Posted
Updated 14-Feb-17 12:37pm
Comments
j snooze 14-Feb-17 17:18pm    
I don't know that I understand exactly what you are trying to do. If you have a List<t> of anything when you define it List<t> MyList = new List<t>();.. you should be able to just do a MyList.Add and continually add more objects to it. Is that not what you are trying to do?
Miguel Altamirano Morales 15-Feb-17 14:00pm    
Thanks for your comment. Yes, the .Add function Works perfectly, what I´m trying to do is accumulate a numeric value at runtime. The type of the List is a data struct which contains a field that I need to increase during an interacion.
I don´t know if you can see the other answers I´m getting for this question, but I´m going to send the code to another person and I hope you can see it too. If you can´t, please tell me and I´ll send it to you also.

1 solution

Arrays in C# AND VB.NET are immutable. Once created they cannot be changed. What ReDim does in VB.NET is fool you into thinking it did just that. It lied to you. What it really did was create an entirely new array with the new dimension and then copied the content from the old array to the new one, then killed the old array.

A List<t> doesn't have that limitation, but it does do something similar behind the scenes. A List<yourstructtype> is far better than a DataTable. DataTables are much heavier, slower, and used to represent database tables, not a list of objects.

Without seeing the code you've written that's involved in this problem it's impossible to say what you're doing wrong.
 
Share this answer
 
Comments
Miguel Altamirano Morales 15-Feb-17 14:15pm    
Such an interesting answer, Dave, I didn´t know that. Thank you very much.

Here´s the code:

- Definition:
public struct DataColores
{
public int id_color;
public string texto;
public double importe;
public string nombre_color;
};
public static List<datacolores> TabColores = new List<datacolores>();

public struct DataKolores
{
public int id_kolor;
public string ktexto;
public double kimporte;
public double total_grupo;
public double total_final;
};
public static List<datakolores> TabKolores = new List<datakolores>();

- Poblating the Lists from an Oledb Data Base:

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

Object[] Datos = new Object[3]; OleDbDataReader Lector;

cmdColores.CommandType = System.Data.CommandType.Text;
Lector = cmdColores.ExecuteReader (System.Data.CommandBehavior.SequentialAccess);

if (Lector.Read() == true)
{
do {
Lector.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]) });
G.TabKolores.Add(new G.DataKolores(){id_kolor = Convert.ToInt32(Datos[0]), ktexto = Convert.ToString(Datos[1]), kimporte = 0, total_grupo = 0, total_final = 0 });
}
while (Lector.Read() == true);
}
Lector.Close();

As you see, the fields named "Importe", "kimporte", "total_grupo" and total_final" in the structs that conforms the Lists are set to zero initially, ´cause I need to accumulate them at runtime.

- When I try to add numeric values:

{
String cadena;
for (Ind = 0; Ind <= G.TotColores; Ind++)
{
cadena = G.TabKolores[Ind].ktexto ;
if (cadena.Trim() == G.strKey.Trim())
{
G.TabKolores[Ind].kimporte += dblImporte; (// Here are the error. It says G.TabKolores[Ind].kimporte cannot be modified because it is not a variable. And so it does for the next two lines).
G.TabKolores[Ind].total_grupo += dblImporte;
G.TabKolores[Ind].total_final += dblImporte;
break;
}
}
if (Ind > G.TotColores)
MessageBox.Show("Clave de color no identificada", G.strKey);
}

I used to do that fine in a Visual Basic Net using a Multidimentional Arrays With a Redim at runtime, when the program knows how many colors are in a speceific table, but now I´m trying to do the same in C#.

Thank you very mucho for your help.
Dave Kreskowiak 15-Feb-17 14:52pm    
This code fragment is incomplete and, frankly, doesn't make as sense at all. What is "G"? Why are you using static variables in what looks like it should be instance? Near the end, you have ... += dblImporte; several times but this variable isn't defined anywhere and the value isn't set anywhere.

Basically, I have no idea what this code is supposed to be doing but I can tell you it's overly complicated for what it appears to be doing.

Also, the formatting of the code is all over the place, making it harder to read, understand, and debug.

If you're using "global" variables, you're making a big mistake.
Miguel Altamirano Morales 15-Feb-17 15:22pm    
I only sent you part of the code, the one I thought involved with my problem. The complete Code is not finished yet, so it has a lot of errors because I´m copying and pasteing from VB to correct it step by step.
G is the name of a Static Class I created in order to use global variables. I need to use them in several forms in my app and that´s what I found in Web to achieve the same perfomance as public variables in a code module in VB Net, I don´t know if C# has another option to achieve this.
The variable ´dblImporte´ is defined as numeric - double in another part of the code, available for all the module, and it arrives with a value to that procedure,I didn´t think was necesary to send you all the code. And yes, I noticed it´s very scaterred. I don´t know if I can send you a text file.
What I really would´t want to do is to bother you or cause you a waste of time, I really appreciate your help and I can send you whatever you need, but just if you want to continue helping me, You have done a lot for me up to this point and I´m really thankful with you.
Dave Kreskowiak 15-Feb-17 16:01pm    
Global variables are a bad idea all around. You're basically giving every part of your code complete access to the variables instead of allowing them to be changed in only controlled circumstances. You're also making your debugging effort considerably harder by using them.

The class where it is used should maintain complete control of the values it contains and only expose certain methods to be able to modify those values.

What's the exact error message? It's not "this is not a variable". Could it be a NullReferenceException or "An object reference is not set to an instance of an object"?
Miguel Altamirano Morales 15-Feb-17 16:50pm    
Give complete access to certain variables in several (almost all of them) forms or modules of my app is exactly what I need to do in this case, but if there´s a better way to do this, I just don´t know how to do it in C#. Anyway, I understand perfectly what you are trying to tell me.

Maybe my problem is that I´m not explaining correctly my goal.

let me try:

- I am coding in C# an app already developed by me in VB Net, that
works fine, just for practicing and learning C# purposes. I want to
learn C# deeper, not VB anymore, I already know very well VB.

- I was using (VB) multidimentional arrays, each one with a colour Id[0], color name[1], and 3 acumulative numeric ítems [2,3 and 4] that needs to be accumulated at runtime. When I tried to do it in C#, I noticed it was not possible, and I just need to do so.

- I found that I cannot use Redim statement anymore for a multidimentional array, so I had to decide using an ArrayList, a List<t> control or a dataTable. I decided a List<> one.

- I read in Web that a List<> control ("TabKolores" in my code) can be typed as a struct in order to handle several fields.

- In that struct type ("DataKolores" in my code) i need at least 3 fields to be updated (sumarized) at runtime ("kimporte", "total_grupo" and "total_final" in my code).

- When I try to add the value contained in a numeric variable ("dblImporte") to the 3 fields in the struct in the List (the same value) then I get the error "It is not posible to modify the returned value of <list> because is not a variable". The message is in spanish, here I´m trying to translate it for you.

I hope this explanation can give you a better scenario of what I´m tring to do. I can send an entire explanation of the whole application if you like.

Thanks again.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900