Convert array of bytes into class? - c#

Currently, I am using structs for this purpose with the following function:
public static T GetStructure<T>(byte* bytes) where T : unmanaged
{
return Unsafe.As<byte, T>(ref bytes[0]);
}
Here's an example of a struct that I would have, note that this does not account for padding, rather it is using the FieldOffset attribute:
public struct BaseObject {
[FieldOffset(0x18)] public int Id;
[FieldOffset(0x39)] public byte bIsActive
}
The issue with this is I'd like to have multiple structs that have the same base, i.e.
public struct AnotherObject {
[FieldOffset(0x250)] public int SomeInt;
}
Where AnotherObject's parent would be BaseObject. From my description, it sounds to me like I'd want to use classes for this instead. How could I use classes for this example (and keep the field offset functionality), or use inheritance with my existing struct system? Note, I'm not looking for an answer like the following:
public struct AnotherObject {
public BaseObject BaseObject;
[FieldOffset(0x250)] public int SomeInt;
}
I'm guessing I could do something like this, since it looks like FieldOffset can be used in classes:
public class BaseObject {
[FieldOffset(0x18)] public int Id;
}
public class AnotherObject : BaseObject {
[FieldOffset(0x250)] public int SomeInt;
}
But I'm not sure how I'd modify my GetStructure function to support classes, as I don't think Unsafe.As would actually intialize a new class (maybe it does, I'm not sure).

Related

Initialize a static parameter at inheritance in c#

I have one base class that is used to declare generic data structures that have a fixed length in a datablock:
public abstract class FixedLengthDataItem
{
// a static field here to store the fixed length?
public sealed void LoadFromBytes(byte[] data)
{
// Check the fixed length here
DoStuff(data, offset);
}
protected abstract void DoStuff(byte[] data);
}
There can be a lot of data structures that have a fixed length and my intent is to describe them in subclasses.
I'd like to know whether there is a possibility to transmit the information about the fixed length when declaring the inheritance in the child classes:
public class ChildClass : FixedLengthDataItem // Specific syntax here?
{
public override void DoStuff(byte[] data)
{
// Some stuff
}
}
I cannot find a syntax like : FixedLengthDataItem(2) or : FixedLengthDataItem<2> that would allow to set the value of a static field that would be declared in the mother class and could be used to "generically" check the length in the LoadFromBytes method (2 in my example).
If there is no way to do it, what could be a smart way to allow anyone to write subclasses making sure that the check that is performed in the LoadFromBytes method checks the right thing?
I thought about something like:
private readonly int _size;
protected FixedLengthDataItem(int size) { _size = size; }
in the base class. And:
public ChildClassFoo() : base(2) { } // or
public ChildClassBar() : base(3) { } // etc.
in the child class(es). But doing this:
a constructor must be declared in each derived class,
more important: a field size will exist in each object whereas the same size applies for all the instances of each derived class which is not very wise I guess.
Here is one way to do it. Not quite as clean as C++ templates but interesting regardless.
public abstract class DataSize
{
protected DataSize(int size)
{
if (size < 0)
throw new ArgumentOutOfRangeException("Must be greater than zero.", nameof(size));
Size = size;
}
public int Size { get; }
}
public abstract class FixedLengthDataItem<TDataSize>
where TDataSize : DataSize, new()
{
public static TDataSize Data { get; } = new TDataSize();
// a static field here to store the fixed length?
public void LoadFromBytes(byte[] data)
{
// Check the fixed length here
if (data.Length != Data.Size)
{
throw new ArgumentException($"Data has size {data.Length} but a size of {Data.Size} was expected.", nameof(data));
}
DoStuff(data);
}
protected abstract void DoStuff(byte[] data);
}
public sealed class ItemData345 : DataSize { public ItemDataSize() : base(345) { } }
public sealed class CustomItem : FixedLengthDataItem<ItemData345>
{
protected override void DoStuff(byte[] data)
{
throw new NotImplementedException();
}
}
Lets say you have 3-4 classes of this size it actually pays of syntax wise.
Space wise is a different story, you'll need so many instances for this to truly be worth it but it is an interesting experiment.
For what you're describing, putting the size on the base class and then specifying it in the derived classes is better than using any sort of static field.
As you showed in your question:
public ChildClassFoo() : base(2) { }
public ChildClassBar() : base(3) { }
a constructor must be declared in each derived class
You've declared two derived classes in your example without constructors.
a field size will exist in each object whereas the same size applies for all the instances of each derived class which is not very wise I guess.
That would be exactly, precisely the point of putting that field in the base class. If every class that inherits from it needs a field size then what you're doing with the base class ensures that. It doesn't matter if two different classes happen to have the same field size.

How to make abstract static properties

I know this can be done for methods by using an interface. But interfaces cannot have fields or static properties (which would not help because it would specify one value for all classes that implement the interface). I could also have default values for the properties at the abstract class. But ideally I'd like to force every inheriting class to implement values for these properties. Values which can then still be used in abstract methods on the abstract class level.
The benefits of each property:
- Abstract; The base class requires this property to be implemented but doesn't specify a value.
- Static; only store one value per type of implementation, instead of per object.
public interface IPiece
{
readonly int Points;
readonly char Letter;
}
public abstract class Piece
{
public static readonly int Points;
public static readonly char Letter;
}
public class King : Piece, IPiece
{
public int Points = 0;
public int Letter = 'K';
}
The standard pattern for solving this is:
public interface IPiece
{
int Points { get; }
char Letter { get; }
}
public class King : IPiece
{
public int Points => 0;
public char Letter => 'K';
}
There is no need to use static at all, since 0 and K are literals, and thus (like static) are effectively stored only once per class.
Note also that I have removed your abstract class - it is not useful as is since there is no logic in it. An abstract class without logic is conceptually equivalent to an interface (which you already have) so is unnecessary at this stage.
If you really want to use a static then you could use:
public class King : IPiece
{
private static int points = 0;
private static char letter = 'K';
public int Points => points;
public char Letter => letter;
}
but there is no major benefit to that.
You cannot have a static abstract property. Static members of the class are not subject to polymorphism. If you wish to have a property defined in abstract class which should be shared by all implementations and you don't know it in compile-time, you can create a Singleton type for it, or a wrapper around if its not type defined in your code. Then you can have something like this:
public abstract class Piece // or interface
{
public SingletonIntWrapper Points { get; }
public SingletonCharWrapper Letter { get; }
}
First, interfaces can have properties, but they can't have fields (as indicated in the comments on the question).
public interface IPiece
{
int Points {get;} // readonly properties in interfaces must be defined like this
char Letter {get;}
}
You also need to have your abstract class inherit from the interface in order for it to have access to the properties defined within it. Because it is an abstract class, you must mark the properties as abstract
public abstract class Piece : IPiece
{
public abstract int Points {get;}
public abstract char Letter {get;}
}
From there, you can create an implementation (King) of your abstract class (Piece). Since this is not an abstract implementation, you must provide implementations of the properties at this time.
public class King : Piece
{
public override int Points {get; private set;} = 0;
public override char Letter {get; private set;} = 'K';
}
Take a look here for further examples on property inheritance.
You should use a const or static readonly backingfield. (There are differences). Also the abstract class and the interface are redundant. Either let all your pieces derive from Piece or let them implement IPiece.
public interface IPiece
{
int Points { get; }
char Letter { get; }
}
public abstract class Piece : IPiece
{
public abstract int Points { get; }
public abstract char Letter { get; }
}
public class King : Piece
{
public const int POINTS = 0;
public const char LETTER = 'K';
public override int Points { get { return POINTS; } }
public override char Letter { get { return LETTER; } }
}
Note:
Now still you cannot use the public const or static readonly in a very usefull way. Because you cannot reach the definition of the value without an instance. For example you cannot get the value of the King.LETTER when enumerating all values to determine what Piece to construct based on a character.

How declare a generic class field inside abstract class

I would like to declare a generic field inside PakFileFormat class in order to be replaceable with concrete types in derived classes.
This will be fine:
public class Pak10File : PakFileFormat
{
public Pak10File()
{
this.toc = new PakFileToc<Pak10FileEntry>();
}
}
How to fix this ?
Thanks.
Related classes
public abstract class PakFileEntry { }
public class Pak10FileEntry : PakFileEntry
{
public long size; // 8 bytes
public long csize; // 8 bytes
public long offset; // 8 bytes
public byte fname_len; // 1 byte
public char[] fname; // variable
}
public class PakFileToc<T> where T : PakFileEntry { }
public abstract class PakFileFormat
{
protected PakFileToc<T>; // ----- This does not compile.
}
You would need to make PakFileFormat generic also in order to make that compile.
In order for this to be useful though, you will probably need to make PakFileFormat implement some kind of non-generic interface.
It is hard to give more detail than this without knowing exactly what you need PakFileFormat to actually do, or how it will be used.
public abstract class PakFileFormat<TPakFile> where TPakFile : PakFileEntry
{
protected PakFileToc<TPakFile> toc;
}
The sub-classes would then look something like:
public class Pak10File : PakFileFormat<Pak10FileEntry>
{
public Pak10File()
{
this.toc = new PakFileToc<Pak10FileEntry>();
}
}

Can you apply a attribute to multiple fields in C#?

This doesn't seem possible, but I'll ask anyway... Is it possible in C# to apply a single attribute to multiple fields at once?
public class MyClass {
[SomeAttribute]
public int m_nVar1;
[SomeAttribute]
public int m_nVar2;
public int m_nVar3;
}
Is there a short-hand method to put the "SomeAttribute" on m_Var1 & m_Var2, but not on m_nVar3? Currently, we are placing the attributes before each field, but it would be nice to put all the fields using a attribute inside a block.
Yes, it's possible:
[SomeAttribute]
public int m_nVar1, m_nVar2;
(but obviously only if the types are the same)
This could work?, but might end up being pretty tedious
public class CustomClass
{
[CustomAttribute]
public dynamic value { get; set; }
}
public class MyClass
{
public CustomClass m_nVar1, var2, var3;
public MyClass()
{
m_nVar1.value = (int)m_nVar1.value;
var2.value = (string)var2.value;
}
}

How can I access a static property of type T in a generic class?

I am trying to accomplish the following scenario that the generic TestClassWrapper will be able to access static properties of classes it is made of (they will all derive from TestClass). Something like:
public class TestClass
{
public static int x = 5;
}
public class TestClassWrapper<T> where T : TestClass
{
public int test()
{
return T.x;
}
}
Gives the error:
'T' is a 'type parameter', which is not valid in the given context.
Any suggestions?
You can't, basically, at least not without reflection.
One option is to put a delegate in your constructor so that whoever creates an instance can specify how to get at it:
var wrapper = new TestClassWrapper<TestClass>(() => TestClass.x);
You could do it with reflection if necessary:
public class TestClassWrapper<T> where T : TestClass
{
private static readonly FieldInfo field = typeof(T).GetField("x");
public int test()
{
return (int) field.GetValue(null);
}
}
(Add appropriate binding flags if necessary.)
This isn't great, but at least you only need to look up the field once...
Surely you can just write this:
public int test()
{
return TestClass.x;
}
Even in a nontrivial example, you can't override a static field so will always call it from your known base class.
Why not just return TestClass.x?
Generics do not support anything related to static members, so that won't work. My advice would be: don't make it static. Assuming the field genuinely relates to the specific T, you could also use reflection:
return (int) typeof(T).GetField("x").GetValue(null);
but I don't recommend it.
Another solution is to simply not make it static, and work with the new() constraint on T to instantiate the object. Then you can work with an interface, and the wrapper can get the property out of any class that implements that interface:
public interface XExposer
{
Int32 X { get; }
}
public class TestClass : XExposer
{
public Int32 X { get { return 5;} }
}
public class XExposerWrapper<T> where T : XExposer, new()
{
public Int32 X
{
get { return new T().X; }
}
}
In fact, you can change that to public static Int32 X on the TestClassWrapper and simply get it out as Int32 fetchedX = XExposerWrapper<TestClass>.X;
Though since whatever code calls this will have to give the parameter T those same constraints, the wrapper class is pretty unnecessary at this point, since that calling code itself could also just execute new T().X and not bother with the wrapper.
Still, there are some interesting inheritance models where this kind of structure is useful. For example, an abstract class SuperClass<T> where T : SuperClass<T>, new() can both instantiate and return type T in its static functions, effectively allowing you to make inheritable static functions that adapt to the child classes (which would then need to be defined as class ChildClass : SuperClass<ChildClass>). By defining protected abstract functions / properties on the superclass, you can make functions that apply the same logic on any inherited object, but customized to that subclass according to its implementations of these abstracts. I use this for database classes where the table name and fetch query are implemented by the child class. Since the properties are protected, they are never exposed, either.
For example, on database classes, where the actual fetching logic is put in one central abstract class:
public abstract class DbClass<T> where T : DbClass<T>, new()
{
protected abstract String FetchQuery { get; }
protected abstract void Initialize(DatabaseRecord row);
public static T FetchObject(DatabaseSession dbSession, Int32 key)
{
T obj = new T();
DatabaseRecord record = dbSession.RetrieveRecord(obj.FetchQuery, key);
obj.Initialize(record);
return obj;
}
}
And the implementation:
public class User : DbClass<User>
{
public Int32 Key { get; private set;}
public String FirstName { get; set;}
public String LastName { get; set;}
protected override String FetchQuery
{ get { return "SELECT * FROM USER WHERE KEY = {0}";} }
protected override void Initialize(DatabaseRecord row)
{
this.Key = DbTools.SafeGetInt(row.GetField("KEY"));
this.FirstName = DbTools.SafeGetString(row.GetField("FIRST_NAME"));
this.LastName = DbTools.SafeGetString(row.GetField("LAST_NAME"));
}
}
This can be used as:
User usr = User.FetchObject(dbSession, userKey);
This is a rather simplified example, but as you see, this system allows a static function from the parent class to be called on the child class, to return an object of the child class.
T is a type, not parameter or variable so you cannot pick any value from any members. Here is a sample code.
public class UrlRecordService
{
public virtual void SaveSlug<T>(T entity) where T : ISlugSupport
{
if (entity == null)
throw new ArgumentNullException("entity");
int entityId = entity.Id;
string entityName = typeof(T).Name;
}
}
public interface ISlugSupport
{
int Id { get; set; }
}
cjk and Haris Hasan have the most-correct answers to the question as asked. However in this comment the OP implies that he is after something else not quite possible in C#: a way to define a contract for a static member in a derived class.
There isn't a way to strictly define this, but it is possible to set up a pattern that may be implied by a base class (or interface); e.g.:
public class TestClass
{
private static int x;
public virtual int StaticX => x;
}
or if not intended to be used directly
public abstract class AbstractTestClass
{
public abstract int StaticX {get;}
}
or (my preference in this contrived example)
public interface ITest
{
int StaticX {get;}
}
Elsewhere, this pattern of a StaticXxx member may be (loosely) associated with implementations that should back the member with static fields (as in TestClass above).
What's kind of fun is that this can be (re)exposed as static by the generic wrapper, because generic statics are isolated to each type used.
public class TestClassWrapper<T> where T : ITest, new()
{
private readonly static T testInstance = new T();
public static int test() => testInstance.x;
}
This uses a new() condition, but an associated static, generic factory pattern for creating ITest (or TestClass or AbstractTestClass) instances may also be used.
However this may not be feasible if you can't have long-lived instances of the class.
In this situation you assume that T is a subclass of TestClass. Subclasses of TestClass will not have the static int x.

Categories