|
-
Feb 24th, 2011, 07:01 PM
#1
[RESOLVED] having an issue making an array
i am VERY new to c# but making good headway. I tried to make an array like this:
Rectangle[,] ScreenGrid = new Rectangle[57, 51];
it seems to work but when i try to do this later:
Code:
private void SetUpScreenGrid()
{
int x; int y; Rectangle square;
for (x = 1; x <= 56; x++)
{
for (y = 1; y <= 50; y++)
{
ScreenGrid[x, y].Right = ScreenGrid[x, y].Left + 10;
}
}
}
i get an error telling me it's read-only. Can anyone explain why and tell me the correct way?
-Thanks! I am undertaking an ambitious project: I am converting my old games submission wormipede line-by-line from vb6/dx7 to vb2010/xna. Your help will be appreciated.
-
Feb 24th, 2011, 10:44 PM
#2
Re: having an issue making an array
You've got two issues there, but neither of them have anything to do with the way you created your array.
First, as the error message says, the Right property is read-only. The value of that property is calculated from the Left and Width properties. If you want the Right to be a certain value, you have to set the Left to that value less the Width. The same goes for Bottom, Top and Height.
In your case though, that doesn't really apply because you're not trying to change the Left. You're trying to set the Right relative to the Left, which means that you want to set the Width. Logically, that would look like this:
csharp Code:
ScreenGrid[x, y].Width = 10;
That code's not valid though, which leads me to your second problem. By virtue of the fact that Rectangle is a value type (structures are value types and classes are reference types), getting an element from the array will actually get a copy. If you set the Width of that copy then the original is unaffected. The copy is immediately discarded though, so code like that can't do anything useful. As a result, the compiler won't even allow it.
What you need to do in such cases is get the copy and assign it to a variable first. You then change the appropriate property of the copy via the variable. Finally, you copy the copy back over the original. That would look like this:
csharp Code:
Rectangle temp = ScreenGrid[x, y]; temp.Width = 10; ScreenGrid[x, y] = temp;
-
Feb 25th, 2011, 02:40 AM
#3
Re: having an issue making an array
i'd rep you but it hasn't been long enough. 
I had actually managed to get the error to go away but i didn't know why. Here's the code i came up with:
Code:
Rectangle[,] ScreenGrid = new Rectangle[57, 51];//Set up in SetUpScreenGrid()
and then
private void SetUpScreenGrid()
{
int x; int y;
for (x = 1; x <= 56; x++)
{
for (y = 1; y <= 50; y++)
{
ScreenGrid[x, y] = new Rectangle(x * 10 + 193 - 10, y * 10 + 51 - 10, 10, 10);
}
}
Window.Title = Convert.ToString (ScreenGrid[40, 40].X) ;//verify it worked
}
I will keep in mind part 2 of your answer as this isn't the only array in this program. This particular one won't be changed after creation (it's a look-up table for screen grids) but the other two will be.
Last edited by Lord Orwell; Feb 25th, 2011 at 02:44 AM.
-
Feb 25th, 2011, 11:10 AM
#4
Re: having an issue making an array
The reason it worked was that you created a NEW instance of the Rectangle and assigned that. It will work any time you assign a rectangle as a whole instead of trying to modify one of the properties of an existing one.
Need to re-register ASP.NET?
C:\WINNT\Microsoft.NET\Framework\v#VERSIONNUMBER#\aspnet_regiis -i
(Edit #VERSIONNUMBER# as needed - do a DIR if you don't know)
-
Feb 25th, 2011, 07:13 PM
#5
Re: having an issue making an array
yeah. That's why i did it that way. It was the only way i could come up with that bypassed a read-only issue.
-
Mar 6th, 2011, 06:53 AM
#6
Re: having an issue making an array
 Originally Posted by jmcilhinney
<snip> Logically, that would look like this:
csharp Code:
ScreenGrid[x, y].Width = 10;
That code's not valid though, which leads me to your second problem. By virtue of the fact that Rectangle is a value type (structures are value types and classes are reference types), getting an element from the array will actually get a copy. If you set the Width of that copy then the original is unaffected. The copy is immediately discarded though, so code like that can't do anything useful. As a result, the compiler won't even allow it.
What you need to do in such cases is get the copy and assign it to a variable first. You then change the appropriate property of the copy via the variable. Finally, you copy the copy back over the original. That would look like this:
csharp Code:
Rectangle temp = ScreenGrid[x, y]; temp.Width = 10; ScreenGrid[x, y] = temp;
Hey JMC not sure if I'm missing something but are you sure of your statement above? foo = ScreenGrid[x,y], yes indeed returns a copy but surely ScreenGrid[x,y].Width = 666 assigns the value type directly with a property set. By using the temporary variable are you not copying 32 (4*4*2) bytes unnecessarily. Forgive me if I'm not understanding.
-
Mar 6th, 2011, 07:30 AM
#7
Re: having an issue making an array
 Originally Posted by Milk
surely ScreenGrid[x,y].Width = 666 assigns the value type directly with a property set.
No it doesn't. This part:
Code:
ScreenGrid[x,y].Width = 666
Gets a copy of the value in the array element so this part:
Code:
ScreenGrid[x,y].Width = 666
is setting a property of that copy. The copy is not assigned to a local variable so it is immediately discarded and the original array element is unchanged. That's how value types work.
-
Mar 6th, 2011, 09:10 AM
#8
Re: [RESOLVED] having an issue making an array
Hmmm... I'm a little confused now. It appears that maybe a change may have been made in VS 2010. I just tested what I've been talking about in VS 2010 and it worked in both C# and VB. I'm absolutely positive that it was the case in VB at least in previous versions. I don't have VS 2008 installed at home so I'm going to defer this until tomorrow where I will test it at work.
-
Mar 6th, 2011, 03:05 PM
#9
Re: [RESOLVED] having an issue making an array
i have tested it in c# and it was working and the array was persistent. I haven't used c# in previous versions so i can't comment one way or another. I thought maybe i wasn't understanding what you were saying. perhaps it was changed? In any case, the original problem was solved because i was trying to assign to the right instead of the width.
-
Mar 6th, 2011, 08:05 PM
#10
Re: [RESOLVED] having an issue making an array
Regarding array access, I would also have expected it to work that accessing the element got you a copy of a value type.
However, looking in the C# lang spec, the part on Array Element Access reads as follows (emphasis mine):
12.3 Array element access
Array elements are accessed using element-access expressions (§7.6.6.1) of the form A[I1, I2, ..., IN], where A is an expression of an array type and each IX is an expression of type int, uint, long, ulong, or can be implicitly converted to one or more of these types. The result of an array element access is a variable, namely the array element selected by the indices.
The elements of an array can be enumerated using a foreach statement (§8.8.4).
This kinda suggests to me that using an array accessor is treated the same as using a variable directly. There is no "retrieval of the value stored at this index" going on. Which would explain the behaviour being seen.
However, I'd advocate avoiding arrays anyway.
-
Mar 6th, 2011, 08:39 PM
#11
Re: [RESOLVED] having an issue making an array
It appears that I was talking through my hat. What I was saying does apply to properties of value types and I guess I just always assumed that it applied to array elements as well but, apparently, it doesn't. This is not allowed:
csharp Code:
var btn = new Button(); btn.Location.X = 100;
for the reasons I mentioned earlier. The Location property returns a copy of the Point value. This is allowed:
csharp Code:
var points = new Point[10]; points[0].X = 100;
because, as EG has shown, arrays access provides direct access to the value and doesn't create a copy. Apologies to all for the bum steer.
-
Mar 6th, 2011, 08:45 PM
#12
Re: [RESOLVED] having an issue making an array
 Originally Posted by jmcilhinney
Apologies to all for the bum steer.
It got me as well. I only went and looked it up after you said your testing gave you those results.
The inconsistency between this and "proper" collection types is yet another thing to add to my list of reasons to avoid arrays (especially in combination with mutable value types!)
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|