I am making a class to abstract some functionality that I will be using in multiple other classes in my project. This class converts objects to and from JSON and also deep copies objects.
public abstract class Serializable
{
public T Copy<T>()
{
return Deserialize<T>(Serialize());
}
public string Serialize()
{
return JsonConvert.SerializeObject(this);
}
public static T Deserialize<T>(string json)
{
return JsonConvert.DeserializeObject<T>(json);
}
}
This code works as intended; however, I would like to simplify the syntax of the Copy
and Desirialize
functions. Currently, a call looks like this copy = descendantClassInstance.Copy<descendantClass>()
which is wordy and also leaves room for error in that copy = otherdescendantClassInstance.Copy<descendantClass>()
would compile but yield an error at runtime. I would prefer the return type be automatically inferred based on the type of the calling object, like copy = descendantClassInstance.Copy()
, without overriding the Copy
or Desirialize
method in each descendant class.
How can I do this?
Edit:
Extensions seem to be a possible avenue for implementing Copy
as desired. However, I also want similar functionality for Deserialize
, which is static. From here, it doesn't seem doable with extensions.
An acceptable answer will handle both of these case.
One option is to use
public abstract class Serializable<T>
{
public T Copy()
{
return Deserialize(Serialize());
}
public string Serialize()
{
return JsonConvert.SerializeObject(this);
}
public static T Deserialize(string json)
{
return JsonConvert.DeserializeObject<T>(json);
}
}
And to implement it like this:
public class Test : Serializable<Test>
{
}
However, note that this will require you to continue the chain if you want further descendants of your class to have the most derived type:
public class Base<T> : Serializable<T> where T : Base<T>
{
}
public class Derived : Base<Derived>
{
}
This may or may not be acceptable depending on your use case.