tags:

views:

77

answers:

1

Hi, I am creating an array as below:

public struct Smb_Parameters
        {
            public byte WordCount;
            public ushort[] Words;
        }

While I assign the values Like below:

Smb_Parameters smbParameter = new Smb_Parameters();
smbParameter.WordCount = 0;
string words= "NT LM 0.12";
smbParameter.Words = Encoding.ASCII.GetBytes(name);

In the above assignment smbParameter.WordCount contains the value 0 but does smbParameter.Words contains directly the values(Arry of byteS) or memory reference to the location that contains the values?

Edit 1:

I want to send a packet to the server . For that I need to convert Smb_Parameters object to array using the following code:

int len = Marshal.SizeOf(Smb_Parameters);
 byte[] arr = new byte[len];
 IntPtr ptr = Marshal.AllocHGlobal(len);
 Marshal.StructureToPtr(Smb_Parameters, ptr, true);
 Marshal.Copy(ptr, arr, 0, len);
 Marshal.FreeHGlobal(ptr);
+2  A: 

Unless you use fixed-size buffers in unsafe code, it will be a reference. In general, it doesn't matter whether a variable is contained within a struct or a class - or indeed whether it's a local variable: the type of the variable decides whether the value is a reference or whether it contains the data directly. Aside from the fixed-size buffers I've mentioned, arrays are always reference types in .NET.

(There's also stackalloc which looks a bit like an array allocation - it allocates a block of memory on the stack. Again, this is only for use in unsafe code, and very rarely encountered in my experience.)

In the example you've given (suitably adjusted to make it compile) Words would definitely be a reference. In particular, if you assign the value to refer to a particular array and then change the contents of that array, the changes will be visible via the struct's variable.

(I'd also strongly recommend that you don't have public fields or mutable value types. Hopefully this was just for the sake of an example though :)

EDIT: To answer the updated question, don't send data like that. It's a horribly fragile way of serializing anything. There are various better options:

  • Use .NET binary serialization (also somewhat fragile in terms of versioning, and not cross-platform)
  • Use XML serialization (probably overkill in this case)
  • Use a third-party serialization framework (e.g. Thrift or Protocol Buffers)
  • Hand-roll serialization with a "ToByteArray" or "WriteToStream" method in your class which serializes each value explicitly. You might want to use BinaryWriter for this.
Jon Skeet
@Jon Skeet, Thanks Jon. But I wont be able to access the Fields (letz Say WordCount via smbParameter if WordCount is not Public. Is there any other way arround
Subhen
@Subhen: Yes - provide a constructor which takes the relevant values, make the fields private, and provide public read-only properties. However, I would advise against putting an array into a struct to start with (if you're providing access to the outside world) as non-empty arrays are always mutable. Is there any reason why you want this to be a struct rather than a class?
Jon Skeet
@Jon Skeet,I was using Struct as unsure of how to get the size of class object. For Struct I am doing this by Marshal.SizeOf(myStruct); The Marshal.SizeOf is not working with Class Object
Subhen
@Subhen: Why do you need to get the size of the type? What's the context here?
Jon Skeet
@Jon Skeet, Edited the Question As I needed to sent a packet to server
Subhen
@Subhen: I've edited my answer. Please don't try to use `Marshal.*` for this.
Jon Skeet