Object created using reflection, serialization error.
zhuxianzhiniko opened this issue · comments
How to reproduce the bug
`public sealed class TestClass
{
public readonly int Id;
public readonly string FirstName;
public TestClass()
{
}
public TestClass(int id, string firstName)
{
this.Id = id;
this.FirstName = firstName;
}
public override string ToString()
{
return $"Id:{Id},FirstName:{FirstName}";
}
}
internal class Program
{
public static void Main(string[] args)
{
try
{
var instance = Activator.CreateInstance(typeof(TestClass));
var idField = typeof(TestClass).GetField("Id");
var firstNameField = typeof(TestClass).GetField("FirstName");
idField.SetValue(instance, 100);
firstNameField.SetValue(instance, "niko");
var serializerConfig = new SerializerConfig();
serializerConfig.Advanced.ReadonlyFieldHandling = ReadonlyFieldHandling.ForcedOverwrite;
CerasSerializer serializer = new CerasSerializer(serializerConfig);
var bytes = serializer.Serialize(instance);
var newinstance = serializer.Deserialize<TestClass>(bytes);
Console.WriteLine(newinstance);//Can be successfully serialized, but the data is wrong.
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
}
Platform
CERAS version 4.1.7
Console Application (.net 4.7)
Are the fields included in the serialization?
Use ceras.GenerateDebugReport
To include either change the defaults, or use a config attribute on the class, or an include attribute on the members.
Check out the tutorial for more details
Are the fields included in the serialization?
Use ceras.GenerateDebugReport
To include either change the defaults, or use a config attribute on the class, or an include attribute on the members.
Check out the tutorial for more details
serialization include field,
My guess is that the object type cannot be serialized correctly.
object instance = new TestClass (); // This way Deserialize will fail.
TestClass instance = new TestClass ();
You must use serializer.Deserialize<object>(bytes);
then
You must always call Serialize and Deserialize using the same type.
In your example here:
serializer.Serialize(instance);
the C# compiler is inferring the generic argument from the argument you're passing.
When you call Serialize<object>(...)
Ceras knows that the "container" type (the type of the variable that contains the value, in your case instnce
) is object
, and that this variable could contain ANY concrete object type, even value types...
Think about it like that, if you had a List<object>
and you put in all sorts of random objects/values, and then iterate over it and serialize it, then, when deserializing again, Ceras has to know the concrete type, so it can know how to even interpret the bytes you provided.
The same concept applies in your case, with a single variable.