1
0
Fork 0
mirror of https://github.com/Ellpeck/MLEM.git synced 2024-11-26 06:28:35 +01:00

added some more utility to JsonTypeSafeWrapper and revert SetData changes

This commit is contained in:
Ell 2021-11-07 00:23:48 +01:00
parent ae559adf26
commit 39138446ea
3 changed files with 31 additions and 9 deletions

View file

@ -16,21 +16,21 @@ namespace MLEM.Data.Json {
private Dictionary<string, JsonTypeSafeWrapper> data; private Dictionary<string, JsonTypeSafeWrapper> data;
/// <inheritdoc /> /// <inheritdoc />
public void SetData<T>(string key, T data) { public void SetData(string key, object data) {
if (EqualityComparer<T>.Default.Equals(data, default)) { if (data == default) {
if (this.data != null) if (this.data != null)
this.data.Remove(key); this.data.Remove(key);
} else { } else {
if (this.data == null) if (this.data == null)
this.data = new Dictionary<string, JsonTypeSafeWrapper>(); this.data = new Dictionary<string, JsonTypeSafeWrapper>();
this.data[key] = new JsonTypeSafeWrapper<T>(data); this.data[key] = JsonTypeSafeWrapper.Of(data);
} }
} }
/// <inheritdoc /> /// <inheritdoc />
public T GetData<T>(string key) { public T GetData<T>(string key) {
if (this.data != null && this.data.TryGetValue(key, out var val)) if (this.data != null && this.data.TryGetValue(key, out var val))
return (T) val.Value; return val.GetValue<T>();
return default; return default;
} }

View file

@ -8,7 +8,7 @@ namespace MLEM.Data.Json {
/// A json type-safe wrapper can be used to wrap any objects of any type before submitting them to a non-specifically typed <see cref="List{T}"/> or <see cref="Dictionary{T,T}"/> that will be serialized using a <see cref="JsonSerializer"/> in cases where <see cref="JsonSerializer.TypeNameHandling"/> is not set to <see cref="TypeNameHandling.None"/>. /// A json type-safe wrapper can be used to wrap any objects of any type before submitting them to a non-specifically typed <see cref="List{T}"/> or <see cref="Dictionary{T,T}"/> that will be serialized using a <see cref="JsonSerializer"/> in cases where <see cref="JsonSerializer.TypeNameHandling"/> is not set to <see cref="TypeNameHandling.None"/>.
/// If any object is not wrapped in this manner, and it has a custom <see cref="JsonConverter"/>, the value deserialized from it might not have the same type as the originally serialized object. This behavior can be observed, for example, when serializing a <see cref="List{T}"/> of <see cref="object"/> entries, one of which is a <see cref="TimeSpan"/>: The <see cref="TimeSpan"/> will be serialized as a <see cref="string"/> and, upon deserialization, will remain a <see cref="string"/>. /// If any object is not wrapped in this manner, and it has a custom <see cref="JsonConverter"/>, the value deserialized from it might not have the same type as the originally serialized object. This behavior can be observed, for example, when serializing a <see cref="List{T}"/> of <see cref="object"/> entries, one of which is a <see cref="TimeSpan"/>: The <see cref="TimeSpan"/> will be serialized as a <see cref="string"/> and, upon deserialization, will remain a <see cref="string"/>.
/// In general, wrapping objects in this manner is only useful in rare cases, where custom data of an unexpected or unknown type is stored. /// In general, wrapping objects in this manner is only useful in rare cases, where custom data of an unexpected or unknown type is stored.
/// See <see cref="JsonTypeSafeGenericDataHolder"/> for an example of how this class and <see cref="JsonTypeSafeWrapper{T}"/> can be used, and see this stackoverflow answer for more information on the problem that this class solves: https://stackoverflow.com/a/38798114. /// See <see cref="JsonTypeSafeGenericDataHolder"/> for an example of how this class can be used, and see this stackoverflow answer for more information on the problem that this class solves: https://stackoverflow.com/a/38798114.
/// </summary> /// </summary>
public abstract class JsonTypeSafeWrapper { public abstract class JsonTypeSafeWrapper {
@ -17,6 +17,28 @@ namespace MLEM.Data.Json {
/// </summary> /// </summary>
public abstract object Value { get; } public abstract object Value { get; }
/// <summary>
/// Returns the current <see cref="Value"/> of this <see cref="JsonTypeSafeWrapper"/>, typecast to the given type <typeparamref name="T"/>.
/// If this <see cref="Value"/>'s type is incompatible with the given type, the type's default value is returned instead.
/// </summary>
/// <typeparam name="T">The type of value to return</typeparam>
/// <returns>The <see cref="Value"/>, castt to the given type if compatible, otherwise default</returns>
public T GetValue<T>() {
return this.Value is T t ? t : default;
}
/// <summary>
/// Creates a new <see cref="JsonTypeSafeWrapper{T}"/> from the given value.
/// The type parameter of the returned wrapper will be equal to the <see cref="Type"/> of the <paramref name="value"/> passed.
/// If a <see cref="JsonTypeSafeWrapper{T}"/> for a specific type, known at comepile type, should be created, you can use <see cref="JsonTypeSafeWrapper{T}(T)"/>.
/// </summary>
/// <param name="value">The value to wrap</param>
/// <returns>A <see cref="JsonTypeSafeWrapper{T}"/> with a type matching the type of <paramref name="value"/></returns>
public static JsonTypeSafeWrapper Of(object value) {
var type = typeof(JsonTypeSafeWrapper<>).MakeGenericType(value.GetType());
return (JsonTypeSafeWrapper) Activator.CreateInstance(type, value);
}
} }
/// <inheritdoc /> /// <inheritdoc />
@ -30,6 +52,7 @@ namespace MLEM.Data.Json {
/// <summary> /// <summary>
/// Creates a new json type-safe wrapper instance that wraps the given <paramref name="value"/>. /// Creates a new json type-safe wrapper instance that wraps the given <paramref name="value"/>.
/// If the type of the value is unknown at compile time, <see cref="JsonTypeSafeWrapper.Of"/> can be used instead.
/// </summary> /// </summary>
/// <param name="value">The value to wrap</param> /// <param name="value">The value to wrap</param>
public JsonTypeSafeWrapper(T value) { public JsonTypeSafeWrapper(T value) {

View file

@ -11,8 +11,8 @@ namespace MLEM.Misc {
private Dictionary<string, object> data; private Dictionary<string, object> data;
/// <inheritdoc /> /// <inheritdoc />
public void SetData<T>(string key, T data) { public void SetData(string key, object data) {
if (EqualityComparer<T>.Default.Equals(data, default)) { if (data == default) {
if (this.data != null) if (this.data != null)
this.data.Remove(key); this.data.Remove(key);
} else { } else {
@ -49,8 +49,7 @@ namespace MLEM.Misc {
/// </summary> /// </summary>
/// <param name="key">The key to store the data by</param> /// <param name="key">The key to store the data by</param>
/// <param name="data">The data to store in the object</param> /// <param name="data">The data to store in the object</param>
/// <typeparam name="T">The type of the data to store</typeparam> void SetData(string key, object data);
void SetData<T>(string key, T data);
/// <summary> /// <summary>
/// Returns a piece of generic data of the given type on this object. /// Returns a piece of generic data of the given type on this object.