Code/Util/SerializableObject.cs
using System.Text.Json;
namespace Nodebox.Util;
public class SerializableObject {
public SerializableObject() { }
public SerializableObject(object obj) : this() {
SerializableType = obj.GetType();
Value = obj;
}
public SerializableObject(Type type, object obj) : this() {
SerializableType = type;
UntypedValue = obj;
}
[JsonInclude]
[Property]
public SerializableType SerializableType { get; set; } = null;
[JsonIgnore]
[Hide]
public Type Type => SerializableType?.Type;
[JsonIgnore]
private object _untypedValue = null;
[JsonInclude]
[Hide]
protected object UntypedValue {
get => _untypedValue;
set {
_untypedValue = value;
_cachedValue = null;
_cachedHashCode = null;
}
}
[JsonIgnore]
private object _cachedValue = null;
[JsonIgnore]
private int? _cachedHashCode = null;
[Property]
[JsonIgnore]
public object Value {
get {
if (UntypedValue is not JsonElement jsonElement) {
return UntypedValue;
}
if (_cachedHashCode != null && _cachedHashCode.Value == SerializableType.GetHashCode()) {
return _cachedValue;
}
var options = new JsonSerializerOptions(JsonSerializerOptions.Default) {
PropertyNameCaseInsensitive = true,
NumberHandling = JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.AllowNamedFloatingPointLiterals,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault
};
options.Converters.Add(new JsonStringEnumConverter(null, true));
_cachedValue = jsonElement.Deserialize(Type, options);
_cachedHashCode = SerializableType.GetHashCode();
return _cachedValue;
}
set {
if (UntypedValue != null) {
Assert.AreEqual(UntypedValue.GetType(), Type);
}
UntypedValue = value;
_cachedValue = null;
_cachedHashCode = null;
// _cachedValue = value;
// _cachedHashCode = SerializableType.GetHashCode();
}
}
public override string ToString() => SerializableType?.Type?.ToSimpleString() ?? "SerializableObject(null)";
}