Assigning a Reference to a Variable

D

Drakemar

Hello all,
Thank you for taking the time to read and help me with my question.

Here is a simplified program I have:


int[,] array2D = { {1, 2, 3}, {4, 5, 6} };


private void Main(){
printarray2DValue(0);
printarray2DValue(1);
}

printarray2DValue(int dValue){
int length;
int i=0;
int x;
int y;
string str;

if (dValue==0){
length = array2D .GetLength(0);
x=i;
y=0;
}
else{
length = array2D .GetLength(1);
x=0;
y=1;
}

for (i;i<length;i++){
str += 2dArray[x,y].ToString();
}
MessageBox.Show(str);
}

Now, that obviously doesn't work how I would want it to. And I can't
say "x= ref i" either because C# won't allow it. I read
http://www.yoda.arachsys.com/csharp/parameters.html, and
http://groups.google.ca/group/micro...lnk=gst&q=reference+variable#18c83a169e66dacb
and I believe my answer is that I can not do what I want, unless I use
unsafe code, or boxing.

The easiest solution is just to split this into two methods, one for
each dimension of the array. But, the more dimensions, the more
methods, and thats not good.

Any suggestions?
 
J

Jon Skeet [C# MVP]

Thank you for taking the time to read and help me with my question.

Here is a simplified program I have:

<snip>

Given that this *doesn't* do what you want it to, could you explain
what you *do* want to achieve? It's not really clear to me at the
moment.

Jon
 
I

Ignacio Machin ( .NET/ C# MVP )

Now, that obviously doesn't work how I would want it to.  And I can't
say "x= ref i" either because C# won't allow it.  I readhttp://www.yoda.arachsys.com/csharp/parameters.html, andhttp://groups.google.ca/group/microsoft.public.dotnet.languages.cshar...
and I believe my answer is that I can not do what I want, unless I use
unsafe code, or boxing.

What wyo uwant to do in the first place? It seems like if you want to
print all the members of one of the given dimensions, but if this is
the case it's pretty convoluted way that you selected.
The easiest solution is just to split this into two methods, one for
each dimension of the array.  But, the more dimensions, the more
methods, and thats not good.

Your code neither works with more than two dimensions to start with.
Any suggestions?

What are you tryong to do?
 
D

Drakemar

I apologize for my utterly unclear example=).

Basically, what I wanted was to have a single function iterate through
the two-dimensional array in a certain dimension based on one
parameter.
So, with the following code, I was wanting to have
printarray2DValue(0) output "123", and printarray2DValue(0) output
"14".

int[,] array2D = { {1, 2, 3}, {4, 5, 6} };

private void Main(){
printarray2DValue(0);
printarray2DValue(1);

}

printarray2DValue(int dValue){
int length;
int i=0;
int x;
int y;
string str;

if (dValue==0){
length = array2D .GetLength(0);
x=i;
y=0;
}
else{
length = array2D .GetLength(1);
x=0;
y=i; //note, this was a typo my first post. I wrote 1 when I
should have wrote i.
}

for (i;i<length;i++){
str += 2dArray[x,y].ToString();
}

MessageBox.Show(str);

}


I looked more into the Func<int> that you suggested and found that the
following solved the problem for me:
int[,] array2D = { {1, 2, 3}, {4, 5, 6} };

private void Main(){
printarray2DValue(0);
printarray2DValue(1);

}

printarray2DValue(int dValue){
int length;
int i=0;
int x;
int y;
string str;
Func<int> xLoc;
Func<int> yLoc;

if (dValue==0){
length = array2D .GetLength(0);
xLoc = (()=>i);
yLoc=0;
}
else{
length = array2D .GetLength(1);
xLoc =0;
yLoc= (()=>i);
}
x = xLoc;
y=yLoc;

for (i;i<length;i++){
str += 2dArray[x(),y()].ToString();
}

MessageBox.Show(str);

}
 
J

Jon Skeet [C# MVP]

I apologize for my utterly unclear example=).

Basically, what I wanted was to have a single function iterate through
the two-dimensional array in a certain dimension based on one
parameter.
So, with the following code, I was wanting to have
printarray2DValue(0) output "123", and printarray2DValue(0) output
"14".

Hang on - so you're talking about going in a different *direction*
rather than just effectively slicing different rows out of a
rectangle?

Jon
 
B

Barry Kelly

Drakemar said:
Thank you for taking the time to read and help me with my question.
The easiest solution is just to split this into two methods, one for
each dimension of the array. But, the more dimensions, the more
methods, and thats not good.

It's an interesting problem. To generalize it to any number of
dimensions, I wrote the following program as a thought exercise. The
Iterate<> method takes a list of dimensions describing the order of
traversal. BTW, the CLR doesn't have instructions for multi-dimensional
array indexing - it uses auto-generate 'get' and 'set' methods - so you
may want to think about simulating a multidimensional array using a
single dimension and multiplication etc., if performance timings warrant
it.

---8<---
using System;

class App
{
static void DoIterate<T>(Array x, Action<T> action,
int[] indexer, int[] dimensionMap, int[] bounds, int dimIndex)
{
if (dimIndex == indexer.Length)
{
action((T) x.GetValue(indexer));
return;
}

int dim = dimensionMap[dimIndex];

for (int i = 0; i < bounds[dim]; ++i)
{
indexer[dim] = i;
DoIterate(x, action, indexer, dimensionMap, bounds,
dimIndex + 1);
}
}

static void Iterate<T>(Array x, Action<T> action,
params int[] dimensionMap)
{
if (x.Rank != dimensionMap.Length)
throw new Exception("Wrong number of dimensions");

int[] bounds = new int[x.Rank];
int[] indexer = new int[x.Rank];

for (int dim = 0; dim < x.Rank; ++dim)
bounds[dimensionMap[dim]] = x.GetLength(dimensionMap[dim]);

DoIterate<T>(x, action, indexer, dimensionMap, bounds, 0);
}

static void Main()
{
int[,] a = { { 1, 2, 3 }, { 4, 5, 6 } };
int[,,] b = { { { 1, 2 }, { 3, 4 } }, { { 5, 6 }, { 7, 8 } } };

Iterate<int>(a, x => Console.Write("{0} ", x), 0, 1);
Console.WriteLine();
Iterate<int>(a, x => Console.Write("{0} ", x), 1, 0);
Console.WriteLine();

Iterate<int>(b, x => Console.Write("{0} ", x), 0, 1, 2);
Console.WriteLine();
Iterate<int>(b, x => Console.Write("{0} ", x), 2, 1, 0);
Console.WriteLine();
Iterate<int>(b, x => Console.Write("{0} ", x), 1, 2, 0);
Console.WriteLine();
}
}
--->8---

-- Barry
 
A

Alun Harford

Peter said:
[...]
for (i;i<length;i++){
str += 2dArray[x,y].ToString();

I have the impression that in this loop, you want "x" to either remain
constant (0, if "dValue" is non-zero) or to follow the value of "i" (if
"dValue" is zero).

This particular example seems odd to me (for one, if "dValue" is
non-zero, then you just keep using the same array element over and
over). But assuming I've understood correctly, there is no direct way
to accomplish what you want.

I accept your challenge! :)

static void printarray2DValue(int dValue)
{
int length;
int i = 0, zero = 0;
TypedReference x, y;
string str="";

if (dValue == 0)
{
length = array2D.GetLength(0);
x = __makeref(i);
y = __makeref(zero);
}
else
{
length = array2D.GetLength(1);
x = __makeref(zero);
y = __makeref(i);
}

for (; i < length; i++)
{
str += array2D[__refvalue(x, int), __refvalue(y, int)].ToString();
}

MessageBox.Show(str);
}

Alun Harford
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top