[.net] Assigning values to Array

Started by
12 comments, last by yaroslavd 18 years, 3 months ago
I want to do something like this:

foreach(Element e in someArray)
  e = new e(...);

However, this gives me an error because you can't assign to a variable you are foreach'ing over. The reason I can't use the standard for-loops is because I don't know the dimensions or the rank of the array. Ultimately, what I want this for is to make an array of the same dimensions as the one I already have, but replace all the elements with element.Name (the array consists of elements of type IRecordable, which has a Name property). Maybe there's already a library function that does this? I couldn't find one. Thank you.
Advertisement
Quote:The reason I can't use the standard for-loops is because I don't know the dimensions or the rank of the array


How is this possible? Arrays have "Length" and "Rank" properties..
As the AP mentioned.
for(int i = 0; i < arr.Length; ++i) {  arr = blah;}

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.

Right, but it could be something like...

IRecordable[][,,][][,][,,,,,,,,]

I mean I guess it's possible, but is there an easier way of doing it?

Edit: Another problem is outlined in my other post on this forum about te Array's rank. Basically, I can find out the number of commas, but not brackets (so to speak), as that is what Array.Rank returns.
I see what you mean. Not only do you have a multidimensional array, the elements within that array are themselves multidimensional arrays. So you have two problems: You need to initialize each array-of-arrays with nested arrays until there is no longer any nesting, at which point you need to initialize the array with new reference types.

Are you writing a generic container class?

void InitializeArray(Array array){  int[] indices = new int[array.Rank];  for (int r=0; r<array.Rank; ++r)    indices[r] = array.GetLength(r);    while (indexes[0] >= 0)  {    // use reflection to create an instance of array.GetType().GetElementType()    // but I can't quickly find out how I did this before.    array.SetValue(instance, indices);        if (array.GetType().GetElementType().GetArrayRank() > 0)    {      InitializeArray(instance as Array);    }        // adjust the multidimensional indices.    for (int r=array.Rank-1; r>=0; --r)    {      if (--indices[r] != 0)        break;    }  }}


Array.GetType().GetElementType() returns the inner array's type for each level of nesting.

Array.Rank obviously returns the rank, like everyone reading this thread knows by now.

Array.GetLength(int rank) returns the length of a particular rank in a multidimensional array.

The ultimate trick is to be able to create the nested array instances. You have to use reflection to do this. I forgot what the "create instance given a System.Type" function is, but I'm sure someone else will know.
Thanks. That really helps. However, the problem is not initializing the array. The thing is, the array I'm creating will be the same exact dimensions as the old one (I'm basically replacing someClassInstance with someClassInstance.someMember). So I can clone the original array (since Arrays are not generic and have no specific type). Some the array is initialized fine, I just have to map the elements correctly. But thanks anyway, I'll give it another go, but I'd appreciate more responses.
I don't know about C#, but would something like..
for each(Element ^%e in someArray)  e = gcnew e(...);
Work in C++/CLI? Not something I've tried.
Quote:Original post by Shinkage
I don't know about C#, but would something like..
for each(Element ^%e in someArray)  e = gcnew e(...);
Work in C++/CLI? Not something I've tried.


If you look at my initial post, that is what I tried to do, but it doesn't work because you can't change values you are foreach'ing over. Also, what does % mean?
I just revisited the documentation of Array, and there is a method ConvertAll<In,Out> (...), which seems to do exactly what I want, except it only takes in one-dimensional arrays. If I understand correctly, a one dimensional array is one without commas, but could have multiple parentheses. Can anyone think of a way to use this method to do what I want or would you recommend starting from scratch?

BTW, I am planning to post the code when and if I come up with a solution.
Quote:Original post by yaroslavd
If you look at my initial post, that is what I tried to do, but it doesn't work because you can't change values you are foreach'ing over. Also, what does % mean?


No, what you originally tried to do is in C++/CLI equivalently written thus...
for each(Element ^e in someArray)  e = gcnew e(...);
The % is called a "tracking reference" in C++/CLI and is roughly equivalent to a garbage collected version of the standard C++ reference (&). Mind, this functionality is only available in Visual Studio 2005 since it's part of C++/CLI and not old style Managed C++.

That being said, I booted it up and tried it out, and it does in fact work. The code I originally suggested ( for each(Element ^%... ) will actually set the values within the array. Sorry, but I don't think C# has any equivalent functionality, at least that I know of.

This topic is closed to new replies.

Advertisement