471,310 Members | 1,044 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,310 software developers and data experts.

Struct that contains an array?

Hello!

I have these following classes:

public struct Move
{
public int From { get; set; }

public int To { get; set; }

public int Captures { get; set; }
}

public class MoveList
{
private Move[] moves = new Move[32];

public int Length { get; private set; }

public void Add(Move move)
{
moves[Length++] = move;
}

public Move this[int index]
{
get
{
return moves[index];
}
}
}

MoveList seems to be a candidate for being a struct. However, I can't seem
to create a struct that contains an array. Is this possible? If so, how does
one do it?

Thanks in advance!

--
Daniel

Aug 19 '08 #1
16 2240
There is nothing special about creating a struct with an array - it
should work fine "as is" - however, I disagree that MoveList would
make a good struct - the Add() etc suggest mutablitly, which is
*always* a bad idea in a struct; in particular, the expectation with a
struct is that it has value-type semantics, but the presence of a
mutable array would bind two isolated structs together in unexpected
ways.

Actually, it is /incredibly/ rare to (correctly) create a struct
in .NET; just leave it as a class... you should only create structs
for (immutable) "value units", for example a "currency
value" (immutably combining a decimal and a currency code), or a "time
range" (immutably combining either 2 DateTimes, or a DateTime and
TimeSpan).

Marc
Aug 19 '08 #2
On Aug 19, 8:50*am, Daniel Lidström <some...@microsoft.comwrote:
I have these following classes:

* *public struct Move
* *{
* * * public int From { get; set; }

* * * public int To { get; set; }

* * * public int Captures { get; set; }
* *}
Mutable structs are really bad news. I suggest you either make this a
class, or make it immutable.
* *public class MoveList
* *{
* * * private Move[] moves = new Move[32];

* * * public int Length { get; private set; }

* * * public void Add(Move move)
* * * {
* * * * *moves[Length++] = move;
* * * }

* * * public Move this[int index]
* * * {
* * * * *get
* * * * *{
* * * * * * return moves[index];
* * * * *}
* * * }
* *}

MoveList seems to be a candidate for being a struct.
Not to me - again, it's mutable. Why would you particularly want it to
be a struct?
However, I can't seem
to create a struct that contains an array.
I don't see why not. You just can't use an instance initializer.
Is this possible? If so, how does one do it?
Well, you'd need to realise that there's no way of stopping "moves"
from being null - structs always have a default constructor, which
just sets all fields to default values (i.e. null in this case).
You could make the array lazily allocated (when fetching or adding)
but really I'm not convinced this should be a struct in the first
place.

Jon
Aug 19 '08 #3
Oh, by the way: Move should also be a class, or should be made
immutable; for example, the following Move would be OK as a struct
(although I'd still question why it isn't simply a class):

public struct Move
{
private readonly int from, to, captues;
public int From { get {return from;}}
public int To { get {return to;}}
public int Captures { get {return captues;}}
public Move(int from, int to, int captures)
{
this.from = from;
this.to = to;
this.captures = captures;
}
}

(again, I still think this looks more like a class than a struct - it
isn't a "measure", which is the most common struct scenario).

Marc
Aug 19 '08 #4
On Aug 19, 12:50*pm, Daniel Lidström <some...@microsoft.comwrote:
Hello!

I have these following classes:

* *public struct Move
* *{
* * * public int From { get; set; }

* * * public int To { get; set; }

* * * public int Captures { get; set; }
* *}

* *public class MoveList
* *{
* * * private Move[] moves = new Move[32];

* * * public int Length { get; private set; }

* * * public void Add(Move move)
* * * {
* * * * *moves[Length++] = move;
* * * }

* * * public Move this[int index]
* * * {
* * * * *get
* * * * *{
* * * * * * return moves[index];
* * * * *}
* * * }
* *}

MoveList seems to be a candidate for being a struct. However, I can't seem
to create a struct that contains an array. Is this possible? If so, how does
one do it?

Thanks in advance!

--
Daniel

MoveList is a structure containing array if Moves... check the
following code.

public struct Move
{
public int From { get; set; }

public int To { get; set; }

public int Captures { get; set; }
}

public struct MoveList
{
private Move[] moves;
public int Length { get; private set; }

public void Add(Move move)
{
if (moves == null)
moves = new Move[32];
moves[Length++] = move;
}

public Move this[int index]
{
get
{
if (Length < index)
throw new Exception("Index out of range");

return moves[index];
}
}
}
static void Main(string[] args)
{
Move m = new Move();
MoveList list = new MoveList();
list.Add(m);

Console.ReadLine();

}

-Cnu
Aug 19 '08 #5
On Aug 19, 1:20*pm, Duggi <DuggiSrinivasa...@gmail.comwrote:
On Aug 19, 12:50*pm, Daniel Lidström <some...@microsoft.comwrote:


Hello!
I have these following classes:
* *public struct Move
* *{
* * * public int From { get; set; }
* * * public int To { get; set; }
* * * public int Captures { get; set; }
* *}
* *public class MoveList
* *{
* * * private Move[] moves = new Move[32];
* * * public int Length { get; private set; }
* * * public void Add(Move move)
* * * {
* * * * *moves[Length++] = move;
* * * }
* * * public Move this[int index]
* * * {
* * * * *get
* * * * *{
* * * * * * return moves[index];
* * * * *}
* * * }
* *}
MoveList seems to be a candidate for being a struct. However, I can't seem
to create a struct that contains an array. Is this possible? If so, howdoes
one do it?
Thanks in advance!
--
Daniel

MoveList is a structure containing array if Moves... check the
following code.

public struct Move
* * * * {
* * * * * * public int From { get; set; }

* * * * * * public int To { get; set; }

* * * * * * public int Captures { get; set; }
* * * * }

* * * * public struct MoveList
* * * * {
* * * * * * private Move[] moves;
* * * * * * public int Length { get; private set; }

* * * * * * public void Add(Move move)
* * * * * * {
* * * * * * * * if (moves == null)
* * * * * * * * * * moves = new Move[32];
* * * * * * * * moves[Length++] = move;
* * * * * * }

* * * * * * public Move this[int index]
* * * * * * {
* * * * * * * * get
* * * * * * * * {
* * * * * * * * * * if (Length < index)
* * * * * * * * * * * * throw new Exception("Index out of range");

* * * * * * * * * * return moves[index];
* * * * * * * * }
* * * * * * }
* * * * }

* * * * static void Main(string[] args)
* * * * {
* * * * * * Move m = new Move();
* * * * * * MoveList list = new MoveList();
* * * * * * list.Add(m);

* * * * * * Console.ReadLine();

* * * * }

-Cnu- Hide quoted text -

- Show quoted text -
As replied by others, for me also, makeing Movelist as a struct does
not make sense. Still If you want to make it...above is the code
snippet...
-Cnu.
Aug 19 '08 #6
Daniel Lidström wrote:
Hello!

I have these following classes:

public struct Move
{
public int From { get; set; }

public int To { get; set; }

public int Captures { get; set; }
}

public class MoveList
{
private Move[] moves = new Move[32];

public int Length { get; private set; }

public void Add(Move move)
{
moves[Length++] = move;
}

public Move this[int index]
{
get
{
return moves[index];
}
}
}

MoveList seems to be a candidate for being a struct. However, I can't
seem to create a struct that contains an array. Is this possible? If so,
how does one do it?

Thanks in advance!
No, the MoveList class should definitely not be a struct. It can be
rewritten to work as a struct, but then it doesn't work properly.
Consider this example:

MoveList first = new MoveList();
MoveList second = first;
first.Add(new Move() { From = 1, To = 10, Captures = 2 });
first.Add(new Move() { From = 2, To = 3, Captures = 0 });
second.Add(new Move() { From = 12, To = 14, Captures = 1 });

Now you have two separate lists that share the same array. The first
list thinks that the array has two items, and the second list thinks
that the array has one item. When you added the item to the second list,
it did overwrite the first item that you added to the first list.

--
Göran Andersson
_____
http://www.guffa.com
Aug 19 '08 #7
check the following code.

While that might work for this sample, creating a mutable struct is a
really, really bad idea...

In this case, why not simply use a List<Move>?

Marc
Aug 19 '08 #8
and when I say "work for this sample", I mean that exact Main() - any
other use that uses the list as a variable, argument, etc - is going
to break very badly; the Length won't get carried, nor will array
creations - but if the array has already been created (by a previous
Add) we could be overwriting data from different calls (i.e. same
array, different Length). I can post some code illustrating this if
you want...

Marc
Aug 19 '08 #9
Now you have two separate lists that share the same array.

Actually I suspect you need to add an item (between "first = " and
"second = ") to initialize the array,, otherwise the first Add on each
creates a separate array - but I was about to post something
alarmingly similar ;-p

Marc
Aug 19 '08 #10
Thanks to all who replied, convincing me that I really should use classes
:-)

I was actually trying to explore what kind of performance I would get from
using value types instead of reference types. Has anyone here done any
testing with unsafe types, to measure performance gains?

--
Daniel

Aug 19 '08 #11
I was actually trying to explore what kind of performance I would get from
using value types instead of reference types. Has anyone here done any
testing with unsafe types, to measure performance gains?
Any performance difference would /generally/ be very small, and highly
dependent on your exact usage. It is incorrect to simply state, for
example "structs are quicker". There are a few *very specific*
scenarios in which struct access might be slighlty quicker due mainly
to not having to de-reference; however, an over-sized struct can have
a negative performance impact as it gets copied around the stack etc
(rather than a reference which takes a relatively small space).
Likewise, if you are only reading data you might be OK, but if you
need to make lots of changes then the intended immutable behavior of
structs may force you to do a lot more work to achieve a simple
update.

"unsafe" is something else again...

In most cases, the de-reference is not a bottleneck. Profile your code
and look for actual problems, otherwise you are doing premature
optimisation: your time could be spent better optimising the actual
problem (in fact, without profiling you are just as likely to make
things worse than better).

Marc
Aug 19 '08 #12
On Aug 19, 2:01*pm, Daniel Lidström <some...@microsoft.comwrote:
Thanks to all who replied, convincing me that I really should use classes
:-)

I was actually trying to explore what kind of performance I would get from
using value types instead of reference types. Has anyone here done any
testing with unsafe types, to measure performance gains?

--
Daniel
My simple suggestion would be, if the size of array is small, go for
struct or else classes are good idea. Also the frequency at which
application access the array also matters :-)

-Cnu.
Aug 19 '08 #13
On Aug 19, 11:39*am, Duggi <DuggiSrinivasa...@gmail.comwrote:
My simple suggestion would be, if the size of array is small, go for
struct or else classes are good idea.
Why? The array itself isn't going to be copied around - it's going to
be a reference either way, unless you use unsafe code and "fixed".
Also the frequency at which
application access the array also matters :-)
More important, IMO, is the maintainability of the code. Micro-
optimisation like this is unlikely to have a significant impact on
performance, but will almost certainly make the code harder to
maintain.

Jon
Aug 19 '08 #14
if the size of array is small, go for struct or else classes are good
idea.
That really has very little to do with the choice between struct and class.

As an aside, the size of structs *is* a factor, but arrays are always
allocated on the heap - MoveList (as a struct) would only contain a
reference (fixed size) to the array, not the array itself.

Marc
Aug 19 '08 #15
Marc Gravell wrote:
>Now you have two separate lists that share the same array.

Actually I suspect you need to add an item (between "first = " and
"second = ") to initialize the array,, otherwise the first Add on each
creates a separate array - but I was about to post something
alarmingly similar ;-p

Marc
Yes, you are correct, as the struct probably needs lazy initialisation
of the array to work at all.

--
Göran Andersson
_____
http://www.guffa.com
Aug 19 '08 #16
On Aug 19, 3:51*pm, "Jon Skeet [C# MVP]" <sk...@pobox.comwrote:
On Aug 19, 11:39*am, Duggi <DuggiSrinivasa...@gmail.comwrote:
My simple suggestion would be, if the size of array is small, go for
struct or else classes are good idea.

Why? The array itself isn't going to be copied around - it's going to
be a reference either way, unless you use unsafe code and "fixed".
Also the frequency at which
application access the array also matters :-)

More important, IMO, is the maintainability of the code. Micro-
optimisation like this is unlikely to have a significant impact on
performance, but will almost certainly make the code harder to
maintain.

Jon
Thanks to Jon and thanks to Marc

I was under a wrong perception. I agree size should not matter here.
And I agree with your opinion about the code maintainability also.

-Cnu
Aug 20 '08 #17

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

7 posts views Thread by seia0106 | last post: by
10 posts views Thread by David Rasmussen | last post: by
3 posts views Thread by Olav Langeland | last post: by
3 posts views Thread by Rudy Velthuis | last post: by
1 post views Thread by Polaris | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.