0

I'm sure this has been asked here already but I can't locate the answer...
In c we have this:

#define COMMAND_ARGUMENTS_SIZE (3)
typedef struct
{
    unsinged char opcode; 
    unsigned char arguments[COMMAND_ARGUMENTS_SIZE];
} Command;

In c# we'd like this:

struct Command
{
    byte opcode;
    byte arguments[...];
}    

The array sizes are in a state of flux and we have them used across several files. We'd like to keep the #define (but we know we can't....). This is a port and we're not about to do major rewrites.

5 Answers 5

4

Mark the type as "unsafe" and use a fixed size buffer.

unsafe struct Command 
{ 
  const int CommandArgumentsSize = 3;
  byte opcode;
  fixed byte arguments[CommandArgumentsSize];
}  

It is easy to get confused between the "fixed" declaration and the "fixed" statement. See my article on the subject if this is confusing.

Alternatively, if you only have three of them then I'd be inclined to:

struct Command 
{ 
  byte opcode;
  byte arg1;
  byte arg2;
  byte arg3;
}  

Easy peasy, no messing around with crazy pointers. If there are only three of them, that's a good solution; if it's a 1000 byte struct then that might not be so hot.

Sign up to request clarification or add additional context in comments.

2 Comments

fixed has to be before the type, not after.
I'm not thrilled about 'fixed' as it leaves me with 'unsafe' which I then have to propogate up the chain, and right now the guy who signs my check is looking at me funny because he wants it done N O W.
2

You can define a constants utility class to hold the "define"-like directives in C#:

public static class Constants
{
    public const int CommandArgumentsSize = 3;
}

struct Command
{
    byte opcode;
    byte[] arguments = new byte[Constants.CommandArgumentsSize];
}

5 Comments

This seems to make life simpler.. however you need a byte[] for 'arguments'.
You don't really need the class, but I think it helps keeping things in place. And thanks for the byte/byte[] type, I've fixed it.
@Gio - What do you mean you don't need a class for consts? You can't put them directly in the namespace nor outside the namespace.
You can put the constant in the same class/struct where it's used (in this case, Command), instead of having a class just for the constants. If this is the only place where it's going to be used, then I'd actually say it's better to do that than inside a "Constants" class. But if it's going to be used in multiple places, I'd prefer to have it in one place where we can easily change.
Personally, I would put the constant where it is most logical: In this case, it would be in Command, and I'd name the constant ArgumentsSize, thus allowing me to refer to it as Command.ArgumentsSize.
0

Use a static class

static class Constants 
{
  public const int DEFAULT_ARRAY_SIZE = 20;
}

It's generally a better idea to encapsulate such knowledge but something like this would not be awful as long as you don't put more than a few constants in there.

Comments

0

Instead of #define use a public const in C#

 struct Command {
    public const int ArgumentSize = 3;
    byte opcode;
    byte[] arguments;
 }

Note: that you have "allocate" the byte array. I would use a class that preallocates:

 class Command {
    public const int ArgumentSize = 3;
    public byte opcode;
    public byte[] arguments = new byte[ArgumentSize];
 }

Comments

0

You can do this:

unsafe struct Command
{
    const int CommandArgumentSize = 3;

    byte opcode;
    fixed byte arguments[CommandArgumentSize];
}

You have to allow unsafe code in your compiler to do this.

If you only want to use it for communication with some unmanaged code, using [MarshalAs(UnmanagedType.ByValArray)] should do the trick too.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.