C
C#15mo ago
Determinism

❔ Is it possible to serialize this struct?

Hello, I want to serialize this struct to json:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct EndOfBarTelegram
{
public static readonly string Key = nameof(EndOfBarTelegram);

public uint MessageLength;
public uint MessageId;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 2)]
public string ProfileType;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 30)]
public string ProfileName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
public string BloomId;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
public string TimeIn;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
public string TimeOut;
public float BarLength;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
public float[] Mean;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
public float[] Max;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
public float[] Min;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
public float[] DefectLength;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct EndOfBarTelegram
{
public static readonly string Key = nameof(EndOfBarTelegram);

public uint MessageLength;
public uint MessageId;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 2)]
public string ProfileType;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 30)]
public string ProfileName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
public string BloomId;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
public string TimeIn;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
public string TimeOut;
public float BarLength;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
public float[] Mean;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
public float[] Max;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
public float[] Min;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
public float[] DefectLength;
}
I'm have these methods:
public static ReadOnlyMemory<byte> SetTJson<T>(T obj)
{
string s = JsonSerializer.Serialize(obj);
return new ReadOnlyMemory<byte>(Encoding.UTF8.GetBytes(s));
}

public static ReadOnlyMemory<byte> SetTJson<T>(T obj, JsonSerializerOptions jsonOptions)
{
string s = JsonSerializer.Serialize(obj, jsonOptions);
return new ReadOnlyMemory<byte>(Encoding.UTF8.GetBytes(s));
}
public static ReadOnlyMemory<byte> SetTJson<T>(T obj)
{
string s = JsonSerializer.Serialize(obj);
return new ReadOnlyMemory<byte>(Encoding.UTF8.GetBytes(s));
}

public static ReadOnlyMemory<byte> SetTJson<T>(T obj, JsonSerializerOptions jsonOptions)
{
string s = JsonSerializer.Serialize(obj, jsonOptions);
return new ReadOnlyMemory<byte>(Encoding.UTF8.GetBytes(s));
}
Is it possible? At the moment it only returns 2 bytes (the curly braces). I'm assuming this has something to do with the marshalling because it works without it
9 Replies
Thinker
Thinker15mo ago
STJ by default doesn't serialize fields You'll have to set IncludeFields in the JsonSerializerOptions to true
Angius
Angius15mo ago
Or turn those fields into properties
Determinism
DeterminismOP15mo ago
I can't turn them into properties because of marshalas
MODiX
MODiX15mo ago
Thinker
REPL Result: Success
using STJ = System.Text.Json;

class Person
{
public string name;
public int age;
}

var p = new Person() { name = "John Doe", age = 30 };
var options = new STJ.JsonSerializerOptions() { IncludeFields = true };
STJ.JsonSerializer.Serialize(p, options)
using STJ = System.Text.Json;

class Person
{
public string name;
public int age;
}

var p = new Person() { name = "John Doe", age = 30 };
var options = new STJ.JsonSerializerOptions() { IncludeFields = true };
STJ.JsonSerializer.Serialize(p, options)
Result: string
{"name":"John Doe","age":30}
{"name":"John Doe","age":30}
Compile: 595.319ms | Execution: 53.097ms | React with ❌ to remove this embed.
Determinism
DeterminismOP15mo ago
That works thanks What if I wanted to make all of the fields readonly? How can I deserialize this?
namespace MillTracking.Shared.Models.Telegrams;

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public readonly record struct EndOfBarTelegram
{
public static readonly string Key = nameof(EndOfBarTelegram);

public readonly uint MessageLength;
public readonly uint MessageId;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 2)]
public readonly string ProfileType;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 30)]
public readonly string ProfileName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
public readonly string BloomId;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
public readonly string TimeIn;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
public readonly string TimeOut;
public readonly float BarLength;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
public readonly float[] Mean;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
public readonly float[] Max;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
public readonly float[] Min;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
public readonly float[] DefectLength;
}
namespace MillTracking.Shared.Models.Telegrams;

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public readonly record struct EndOfBarTelegram
{
public static readonly string Key = nameof(EndOfBarTelegram);

public readonly uint MessageLength;
public readonly uint MessageId;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 2)]
public readonly string ProfileType;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 30)]
public readonly string ProfileName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
public readonly string BloomId;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
public readonly string TimeIn;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
public readonly string TimeOut;
public readonly float BarLength;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
public readonly float[] Mean;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
public readonly float[] Max;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
public readonly float[] Min;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
public readonly float[] DefectLength;
}
public static T? DecodeJson<T>(ReadOnlyMemory<byte> buffer, JsonSerializerOptions? jsonOptions = null)
{
try
{
JsonSerializerOptions options = jsonOptions ?? defaultJsonOptions;
T val = JsonSerializer.Deserialize<T>(Encoding.UTF8.GetString(buffer.Span), options);
return (val != null) ? val : default(T);
}
catch (Exception)
{
return default(T);
}
}
public static T? DecodeJson<T>(ReadOnlyMemory<byte> buffer, JsonSerializerOptions? jsonOptions = null)
{
try
{
JsonSerializerOptions options = jsonOptions ?? defaultJsonOptions;
T val = JsonSerializer.Deserialize<T>(Encoding.UTF8.GetString(buffer.Span), options);
return (val != null) ? val : default(T);
}
catch (Exception)
{
return default(T);
}
}
MODiX
MODiX15mo ago
Thinker
REPL Result: Success
using STJ = System.Text.Json;

readonly struct Person
{
public readonly string name;
public readonly int age;

public Person(string name, int age) => (this.name, this.age) = (name, age);
}

var options = new STJ.JsonSerializerOptions() { IncludeFields = true };
STJ.JsonSerializer.Deserialize<Person>("""{"name":"John Doe","age":30}""", options)
using STJ = System.Text.Json;

readonly struct Person
{
public readonly string name;
public readonly int age;

public Person(string name, int age) => (this.name, this.age) = (name, age);
}

var options = new STJ.JsonSerializerOptions() { IncludeFields = true };
STJ.JsonSerializer.Deserialize<Person>("""{"name":"John Doe","age":30}""", options)
Result: Person
{
"name": null,
"age": 0
}
{
"name": null,
"age": 0
}
Compile: 681.216ms | Execution: 69.224ms | React with ❌ to remove this embed.
Thinker
Thinker15mo ago
can't do it
Determinism
DeterminismOP15mo ago
got it
Accord
Accord15mo ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server