In my app I am receiving binary data through UDP, I wrote a binary reader that is going field by field and reading appropriate type and assigning it to model manually. Is there a way to define model in a way that will tell some kind of (de)serializer where to look for certain field instead of assigning everything?
Some fields may be arrays - their sizes are known and fixed, but model is unaware of this.
Example (current code):
byte Field1 = binaryReader.ReadByte();
sbyte Field2 = binaryReader.ReadSByte();
float[] Field3 = ...
//etc.
Desired code:
public class Model
{
[BinaryPosition(1)]
public byte Field1 { get; set;}
[BinaryPosition(2)]
public sbyte Field2 { get; set; }
[BinaryPosition(3)]
public float[] Field3 { get; set; }
}
//...
var model = BinaryDeserializer.Deserialize<Model>(byteBuffer);
There are many ways of doing this, increasing in cost and complexity the more features you require.
Starting from the simplest, a POCO struct that works with, as POCO implies, plain C types (byte, int, basically unmanaged value types, no string or anything). In your example, that would be:
struct Model
{
public byte Field1;
public sbyte Field2;
}
There's many ways of converting your byte[] array to that structure, in order of efficiency (and version of .Net): MemoryMarshal.Cast, fixed+pointers and Marshal.PtrToStructure.
If you require more complex objects like strings, you need to use the MarshalAs attribute to declare how you want to pack the string, typically as a value array or less typically as a pointer, and then you need to use Marshal.PtrToStructure to have the marshaller silently handle all the extra copies for you. Obviously, much less efficient.
Related
I need a simple data structure to store 4 data types, an ImageSource, a Brush, a string and an enumeration so I am thinking of using a struct instead of a class:
public struct myData
{
public myData(ImageSource myImg, Brush myBrush, string myText, myEnum e)
{
MyImage = myImg;
MyBrush = myBrush;
MyText = myText;
MyEnum = myEnum;
}
public ImageSource MyImage { get; }
public Brush MyBrush { get; }
public string MyText { get; }
public myEnum MyEnum { get; }
}
This struct will only be used as a private within a class as a way of storing the last data received and restored it again in some circumstances.
I have read the MS guideline about choosing between an struct or class and they finally say:
CONSIDER defining a struct instead of a class if instances of the type
are small and commonly short-lived or are commonly embedded in other
objects.
AVOID defining a struct unless the type has all of the following
characteristics:
It logically represents a single value, similar to primitive types (int, double, etc.).
It has an instance size under 16 bytes.
It is immutable.
It will not have to be boxed frequently.
In all other cases, you should define your types as classes.
... but I am asking this because I follow having doubt in my particular case. So what's better, struct or class here?
From my point of view, you should better use classes, and use properties in classes.
As vadim said, if you have no special needs, try to use classes.
Also as Bagus Tesa said, ImageSource does not conform to AVOID defining a struct unless the type has all of the following characteristics: It logically represents a single value, similar to primitive types (int, double, etc.).
But this question is very subjective, and ultimately it's up to you to understand.
I'm translating a library written in C++ to C#, and the keyword 'union' exists once. In a struct.
What's the correct way of translating it into C#? And what does it do? It looks something like this;
struct Foo {
float bar;
union {
int killroy;
float fubar;
} as;
}
You can use explicit field layouts for that:
[StructLayout(LayoutKind.Explicit)]
public struct SampleUnion
{
[FieldOffset(0)] public float bar;
[FieldOffset(4)] public int killroy;
[FieldOffset(4)] public float fubar;
}
Untested. The idea is that two variables have the same position in your struct. You can of course only use one of them.
More informations about unions in struct tutorial
You can't really decide how to deal with this without knowing something about how it is used. If it is merely being used to save space, then you can ignore it and just use a struct.
However that is not usually why unions are used. There two common reasons to use them. One is to provide 2 or more ways to access the same data. For instance, a union of an int and an array of 4 bytes is one (of many) ways to separate out the bytes of a 32 bit integer.
The other is when the data in the struct came from an external source such as a network data packet. Usually one element of the struct enclosing the union is an ID that tells you which flavor of the union is in effect.
In neither of these cases can you blindly ignore the union and convert it to a struct where the two (or more) fields do not coincide.
In C/C++ union is used to overlay different members in the same memory location, so if you have a union of an int and a float they both use the same 4 bytes of memory to store, obviously writing to one corrupts the other (since int and float have different bit layout).
In .Net Microsoft went with the safer choice and didn't include this feature.
EDIT: except for interop
If you're using the union to map the bytes of one of the types to the other then in C# you can use BitConverter instead.
float fubar = 125f;
int killroy = BitConverter.ToInt32(BitConverter.GetBytes(fubar), 0);
or;
int killroy = 125;
float fubar = BitConverter.ToSingle(BitConverter.GetBytes(killroy), 0);
You could write a simple wrapper but in most cases just use an object it is less confusing.
public class MyUnion
{
private object _id;
public T GetValue<T>() => (T)_id;
public void SetValue<T>(T value) => _id = value;
}
Personally, I would ignore the UNION all together and implement Killroy and Fubar as separate fields
public struct Foo
{
float bar;
int Kilroy;
float Fubar;
}
Using a UNION saves 32 bits of memory allocated by the int....not going to make or break an app these days.
public class Foo
{
public float bar;
public int killroy;
public float fubar
{
get{ return (float)killroy;}
set{ killroy = (int)value;}
}
}
Recently a compiler warning and (very useful) hint prompted me to write the code below.
I had no idea you could do this, but it is perfectly legal, and also convenient in that I can declare a managed struct with public properties similar to public fields of an unmanaged struct, and also initialize it with an object instead of having to pass all the fields as parameters.
What confuses me is that this appears to call the explicit parameterless constructor, which would of course be illegal for this struct.
What's going on here, and has this syntax always been supported?
internal struct IconEntry
{
public byte Width { get; set; }
public byte Height { get; set; }
public byte ColorCount { get; set; }
public byte Reserved { get; set; }
public short Planes { get; set; }
public short BitCount { get; set; }
public int BytesInRes { get; set; }
public int ImageOffset { get; set; }
public IconEntry(BinaryReader reader)
: this()
{
Width = reader.ReadByte();
Height = reader.ReadByte();
ColorCount = reader.ReadByte();
Reserved = reader.ReadByte();
Planes = reader.ReadInt16();
BitCount = reader.ReadInt16();
BytesInRes = reader.ReadInt32();
ImageOffset = reader.ReadInt32();
}
}
A struct always has a public parameterless constructor which can't be overriden: http://msdn.microsoft.com/en-us/library/aa288208%28v=vs.71%29.aspx
This means that a user still would be able to create an instance of this struct that is not initialized according to your logic but with default values for all properties:
var s = new IconEntry();
All structs have a parameterless constructor - it's just implicit (e.g. it always exists with a default routine - one that sets all values to 0) - you just can't have an explicit one (e.g. one that you define yourself in code).
Is there any reason you're exposing properties rather than fields for your struct? If the semantics of your data type imply that
The entire state of an instance will be fully defined by the values exposed by some public members, such that two instances for whom all those report or contain identical values will be considered identical.
Instances of the struct with any combination of values for the aforementioned members may be created easily, given the desired values in question.
that sounds like a perfect fit for a PODS (Plain Old Data Struct). Exposed fields are more efficient and less quirky than struct properties. Given that all struct types always expose all fields for mutation or capture by struct assignment, the encapsulation offered by struct properties is of extremely limited value.
The way you have your constructor written, your struct will have all fields set to all-bits-zero, and then be passed repeatedly to methods which will update one field at a time with the desired value. The fact that the struct is specified as initialized to all-bits-zero by the this will make the compiler happy, but using many individual properties to set up fields piecemeal is inefficient.
Incidentally, even better than a constructor in many cases would be a static method which simply takes your struct as a ref parameter. In many cases, using a constructor with a struct will result in an unnecessary copy operation which could be avoided by using a static method with a ref parameter.
Since structs are value types, it's data members should be initialized if you are explicitly invoke the constructor. And mention "this()" to intimate compiler to complete the assignment of auto implemented properties if anything you mentioned.
struct Student
{
string _sname;
public int ID
{
get; set;
}
internal Student(string sname):this()
{
_sname = sname;
}
internal void PrintDetails()
{
Console.WriteLine("ID : {0} Name: {1}", ID, _sname);
}
}
Main method:
class Program
{
static void Main()
{
Student st = new Student("John")
{
ID=101
};
st.PrintDetails();
}
}
Output:
ID : 101 Name: John
If you are not mention "this()", compiler forcefully ask you to complete the full assignment of ID property.
If you are not explicitly invoke the constructor, compiler implicitly set default values for the struct data members.
public struct Cache {
public int babyGangters { get; set; }
public int punks { get; set; }
public int ogs { get; set; }
public int mercs { get; set; }
public int hsPushers { get; set; }
public int collegeDealers { get; set; }
public int drugLords { get; set; }
public int streetHoes { get; set; }
public int webcamGrls { get; set; }
public int escort { get; set; }
public int turns { get; set; }
public int cash { get; set; }
public int bank { get; set; }
public int drugs { get; set; }
public int totalValue { get; set; }
public int attackIns { get; set; }
public int attackOuts { get; set; }
public int status { get; set; }
public int location { get; set; }
}
That's not only too big by most guidelines, but it's also mutable. That's a much bigger red flag in my view.
Mutable structs can cause unexpected behaviour in many situations. Just say "no".
Why do you want this to be a struct in the first place? And does it really need to be mutable?
The rule of thumb is that a struct should not be bigger than 16 bytes (according to the Framework Design Guidelines). Your struct is 76 bytes (= 19 * 4), so it is pretty big. However, you will have to measure the performance. Big structs can be beneficial for some applications.
The Framework Design Guidelines state:
Avoid defining a struct unless the
type [...] an instance size under 16
bytes.
One of the annotations from Jeffrey Richterto this guidlines state:
Value types can be more than 16
bytes if you don't intend to pass them
to other methods or copy them to and
from a collection class (like an
array).
There is no hard and fast rule as to what constitutes a struct that is too big. There several guidelines available. Most notably the .Net Design Guidelines which recomend a struct not exceed 16 bytes in size.
However these are just guidelines. Whether or not a struct is too big depends highly on the context in which it is used. For example if the struct is created once and only passed by ref / out to all functions then it's size is much less important than one which is frequently passed by value.
In .Net, use classes unless you have a good reason not to. "I want it on the stack" with no other qualifiers is not usually a good reason.
http://www.codeproject.com/KB/cs/structs_in_csharp.aspx
struct improve memory e speed performance, but must be small, in this case utilize a class.
If the item is a struct, any attempt to change a field will only change the field in that particular struct instance. In some circumstances, .net will create temporary struct instances, and if you're not careful your attempts to change a field will simply change the field in that temp instance, rather than in anything more persistent. That is the 'gotcha' that Jon Skeet is warning you about.
On the other hand, a struct variable does have the advantage that value types within it can only be changed if that variable itself is written. The risk that an attempt to change a temporary struct might fail (described above) should be weighed against the risk that an two class variables might get aliased to the same object when they should in reality point to two different objects which happen to have the same property values. If that happens, a change to one variable might accidentally change the other.
One way to think of a struct is like a class which gets cloned any time it gets passed around, but with a cloning operation that's cheaper than that of a class. If 10%-50% or more of the uses of a class would require that it be cloned, you're probably better off with a struct. If you would mostly be using it without cloning it, use a class.
BTW, I wouldn't bother with settable properties; if something is settable, just make the field public. Since structs can't be inherited, there's no loss of generality.
It's impossible to answer that because this depends on your application and usage.
However, yes, with this much data you should really think about creating a class instead of a struct.
You could also ask yourself if you can logically group some of those fields into structs or classes.
The decision as to whether or not to use a struct should be based more on how you want to use it than on how large it is. You should ask yourself if there's any compelling benefit to making this a struct instead of a class. Do you really need value type semantics? Do you need to allocate tens of millions of these things and can't pay the allocation overhead (12 or 24 bytes, depending on the platform) if they're classes? I suspect that the answer to both of those questions is "No", so it's likely that you want to make this thing a class rather than a struct.
I have what amounts to a multi-dimensional array.
int[][][] MyValues;
What I want is to access the indexes via a strongly typed equivelent, such as an enumeration. I'm aware that you can get the enumeration values from the Enum type, but it's a bit long winded for my tastes.
I'd rather have a way to Strongly type the indexes.
For example:
int CarNumber = MyValues[Racetrack.Daytona][Race.Daytona500][Driver.JGordon];
This would, by virtue of it being enum-like, prevent any out of bounds exceptions from being thrown, plus it gives all the indexes a nice human readable meaning.
I've implemented this using a dictionary approach, but it seems kind of heavy handed:
Dictionary<Racetrack,Dictionary<Race,<Dictionary<Driver,int>>> =
new Dictionary<Racetrack,Dictionary<Race,<Dictionary<Driver,int>>>();
which I can then access via enums, but I don't really like this approach. It seems "ugly".
I'm looking for some alternate methods to represent what is essentially a multi-dimensional array while using human readable indexers, while maintaining type safety (can't accidently use a Driver for a Race, for instance, so simply using consts is not a good approach).
Any suggestions?
This will be a compile time array (example above is not real, just an illustration) so I don't have to worry about inserts or deletes or other manipulations of the array. It will stay immutable, both in values, size and layout.
Using a static class with const values is not a good approach either, since it doesn't enforce that only the set of values defined can be passed as indexers.
It sounds to me that you want to use indexers rather than an array. Assuming the following enums (Formula 1 based!):
public enum Track
{
Spielberg,
Adelaide,
Casablanca,
Liverpool,
Melbourne,
Berlin,
Sakhir,
}
public enum Constructor
{
BMW,
Ferrari,
McLaren,
Toyota,
Williams
}
public enum Driver
{
Hamilton,
Kovalainen,
Raikkonen,
Nakajima,
Glock
}
the basic structure is as follows:
public class Race
{
int Year { get; set; }
Track Track { get; set; }
Driver[] Placings { get; set; }
public int this[Driver driver] { } // placing by driver
}
public class Results
{
YearResults this[int index] { }
DriverResults this[Driver index] { }
TrackResults this[Track index] { }
ConstructorResults this[Constructor index] { }
}
public class YearResults
{
YearDriverResults this[Driver index] { }
}
This of course is a partial implementation but you can do some pretty cool things with indexers this way. Like you can access your information with any combination of values in any order (assuming you set up all the intermediate classes).
Its wordier than a multidimensional array or a tuple-keyed Dictionary but I think will give you far more elegant code.
How about using a triple <Racetrack,Race,Driver> as the key (define your own class) in the Dictionary?
If you really need to use an array, I don't think you can do better than wrapping it in a custom class that allows access only using Racetrack, Race, Driver enums.
Obvious question.. Will List<T> not work for you?
Are the enums reasonably small, with values 0...n? If so, you could use a multi-dimensional array but expose an indexer. Note that the code below uses a rectangular array rather than a jagged array, but you could fairly easily adapt it.
// In a static class somewhere. Just a convenience method to check
// whether a value is defined or not. See comment in indexer.
public static void CheckDefined<T>(this T value, String name)
where T : struct
{
if (!Enum.IsDefined(typeof(T), value))
{
throw new ArgumentOutOfRangeException(name);
}
}
// Somewhere else...
private static int GetLength<T>() where T : struct
{
return Enum.GetValues(typeof(T)).Length;
}
private int[,,] array = new int[GetLength<Racetrack>(),
GetLength<Race>(),
GetLength<Driver>()];
public int this Car[Racetrack racetrack, Race race, Driver driver]
{
get
{
// If you don't care about just getting an
// IndexOutOfRangeException, you could skip these three lines.
racetrack.CheckDefined("racetrack");
race.CheckDefined("race");
driver.CheckDefined("driver");
return array[(int) racetrack, (int) race, (int) driver);
}
}
I don't think the dictionary approach is bad, but it isn't elegant. If you created an alias for your dictionary of dictionary things would look better:
using RaceSetup = Dictionary<Racetrack,Dictionary<Race,<Dictionary<Driver,int>>>;
Or you could create a class that derived from the dictionary:
class RaceSetup : Dictionary<Racetrack,Dictionary<Race,<Dictionary<Driver,int>>>
{}