Struct that contains an array?

  • Thread starter Thread starter Daniel Lidström
  • Start date Start date
D

Daniel Lidström

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!
 
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
 
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
 
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
 
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!


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
 
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!

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.
 
Daniel said:
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.
 
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
 
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
 
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
 
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?
 
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
 

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

Back
Top