I have the following class
public abstract class Settings
{
private string _filename;
protected virtual void defaults()
{
}
public static T Load<T>(string filename) where T : Settings, new()
{
T theSetting;
if (File.Exists(filename))
{
var reader = new StreamReader(filename);
var configJson = reader.ReadToEnd();
reader.Close();
theSetting = System.Text.Json.JsonSerializer.Deserialize<T>(configJson);
}
else
{
theSetting = new T();
theSetting.defaults();
}
theSetting._filename = filename;
theSetting.Save();
return theSetting;
}
public void Save()
{
var writer = new StreamWriter(_filename);
writer.Write(JsonSerializer.Serialize(this));
writer.Close();
}
public void SaveAs(string filename)
{
_filename = filename;
Save();
}
}
I know that polymorphic is not supported in .NET Core but I found several answers here
Is polymorphic deserialization possible in System.Text.Json?
The problem is that all the answers are for situations where we have a model class But in my example, the model class is not specified and is created by the user.
I also tried this answer and it worked without any problems But I do not want to use an external library in my project
use this
public class PolymorphicJsonConverter<T> : JsonConverter<T>
{
public override bool CanConvert(Type typeToConvert)
{
return typeof(T).IsAssignableFrom(typeToConvert);
}
public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
throw new NotImplementedException();
}
public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
{
if (value is null)
{
writer.WriteNullValue();
return;
}
writer.WriteStartObject();
foreach (var property in value.GetType().GetProperties())
{
if (!property.CanRead)
continue;
var propertyValue = property.GetValue(value);
writer.WritePropertyName(property.Name);
JsonSerializer.Serialize(writer, propertyValue, options);
}
writer.WriteEndObject();
}
}
and when you want serialize:
options.Converters.Add(new PolymorphicJsonConverter<T>());
string json = JsonSerializer.Serialize(this, options);
Maybe just split Data and class, you can avoid this issue.
public abstract class Settings<T>
{
protected T _t;
protected virtual void defaults()
{
}
public static T Load<T>(string filename)
{
//....
}
public void Save()
{
var writer = new StreamWriter(_filename);
writer.Write(JsonSerializer.Serialize(_t));
writer.Close();
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.