1

Say I have a struct defined as such

struct Student
{
  int age;
  int height;
  char[] name[12];
}

When I'm reading a binary file, it looks something like

List<Student> students = new List<Student>();
Student someStudent;

int num_students = myFile.readUInt32();
for (int i = 0; i < num_students; i++)
{
   // read a student struct
}

How can I write my struct so that I just need to say something along the lines of

someStudent = new Student();

So that it will read the file in the order that the struct is defined, and allow me to get the values as needed with syntax like

someStudent.age;

I could define the Student as a class and have the constructor read data and populate them, but it wouldn't have any methods beyond getters/setters so I thought a struct would be more appropriate.

Or does it not matter whether I use a class or struct? I've seen others write C code using structs to read in blocks of data and figured it was a "good" way to do it.

MxLDevs
  • 19,048
  • 36
  • 123
  • 194
  • 1
    [`[StructLayout(LayoutKind.Sequential)]`](http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.layoutkind.aspx) is where you would start. – Joe Aug 10 '12 at 21:12
  • 1
    possible duplicate of [How to read a binary file using c#?](http://stackoverflow.com/questions/5463476/how-to-read-a-binary-file-using-c) – Scott Chamberlain Aug 10 '12 at 21:14
  • For some reason the accepted answer there makes it seems like using structs would make the code harder to read. I mean, there's all those extra things going on. – MxLDevs Aug 10 '12 at 21:17
  • While you can read a struct in C# "the C++ way", it's complicated. Is there any reason you can't just read the fields one by one, using the relevant methods in BinaryReader? – harold Aug 10 '12 at 21:20
  • Not really. I was just experimenting with ways of trying to make my code easier to follow. When someone goes to that loop and sees me just reading a set of "Student" structs they'll know that it's just student data there. They might not even care what a Student is composed of. – MxLDevs Aug 10 '12 at 21:22

2 Answers2

1

There is not, AFAIK, a low-level direct-layout struct reader built into .NET. You would want want to look at BinaryReader, reading each field in turn? Basically, ReadInt32() twice, and ReadChars(). Pay particular attention to the encoding of the character data (ASCII? UTF8? UTF-16?) and the endianness of the integers.

Personally, I'd look more at using a dedicated cross-platform serializer!

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • A serializer like... protobuf-net? Great implementation of protocol buffers. Thanks for doing that. – Eric J. Aug 10 '12 at 21:41
0

If you want to serialize / deserialize the struct

If you want to read/write the entire struct to a binary file (serialization), I suggest you look at

https://stackoverflow.com/a/629120/141172

Or, if it is an option for you, follow @Marc's advice and use a cross-platform serializer. Personally I would suggest protobuf-net which just happens to have been written by @Marc.

If you are loading from an arbitrary file format

Just like a class, a struct can have a constructor that accepts multiple parameters. In fact, it is generally wise to not provide setters for a struct. Doing so allows the values of the struct to be changed after it is constructed, which generally leads to programming bugs because many developers fail to appreciate the fact that struct is a value type with value semantics.

I would suggest providing a single constructor to initialize your struct, reading the values from the file into temporary variables, and then constructing the struct with a constructor.

public stuct MyStruct
{
    public int Age { get; private set; }
    public int Height { get; private set; }
    private char[] name;
    public char[] Name 
    {
        get { return name; }
        set
        {
            if (value.Length > 12) throw new Exception("Max length is 12");
            name = value;
        }
    }
    public MyStruct(int age, int height, char[] name)
    {
    }
}

To dig further into the perils of mutable structs (ones that can be changed after initialized) I suggest

Why are mutable structs “evil”?

Community
  • 1
  • 1
Eric J.
  • 147,927
  • 63
  • 340
  • 553
  • I am not sure what "constructing the struct with a constructor" would look like. Is it the same constructor that initialized the struct and read temporary values? – MxLDevs Aug 10 '12 at 21:26