Reputation: 1534
My base class has a method to serialize itself that I want derived classes to use.
public abstract class Base
{
public int Property1 { get; set; }
public virtual string Serialize()
{
...
return System.Text.Json.JsonSerializer.Serialize(this, jsonSerializerOptions);
}
}
The problem is that "this" in the base classes refers to the base class. When calling Serialize() from derived classes, only the properties of the base class are serialized. What can I use instead of "this" to pass to the Json serializer so that it will refer to the instance of the derived class.
Derived class may look like this:
public class Derived : Base
{
public int Property2 { get; set; }
}
I then call the Serialize() method like this:
Derived derived = new Derived();
string json = derived.Serialize();
Only Property1 is serialized.
Upvotes: 0
Views: 472
Reputation: 5632
The overload method you are using is Serialize< BaseClass >(this, options). This when called from the base class always pass the BaseType
as T
.
Fortunately, JsonSerializer
provides another overload which you can use from baseclass and achieve the desired behavior without overriding in derived class. For this, You should be using Serialize(this,this.GetType(),options). this.GetType()
wil always returns the instance type even when call is done from a base class.
Upvotes: 0
Reputation: 1731
we can't change 'this' behavior, but you can try below solution, its work like what you need
class Program
{
static void Main(string[] args)
{
Derived d = new Derived();
Console.WriteLine(d.Serialize());
Console.ReadLine();
}
}
public abstract class Base
{
public int Property1 { get; set; }
}
public class Derived : Base
{
public int Property2 { get; set; }
}
public static class Extensions
{
public static string Serialize(this Base obj)
{
return System.Text.Json.JsonSerializer.Serialize((object)obj);
}
}
Upvotes: 1
Reputation: 177
The reason of it serialize Property1 only is you didn't override the virtual method in the derived class, So it works only for property1.
Sample:
public abstract class Base
{
public int Property1 { get; set; } = 20;
public virtual void Display()
{
MessageBox.Show(Property1.ToString());
}
}
public class Derived : Base
{
public int Property2 { get; set; } = 9;
public override void Display() //without this you can't achieve what you want
{
base.Display();
MessageBox.Show(Property2.ToString());
}
}
public class Test
{
public void ShowResult()
{
Derived derived = new Derived();
derived.Display();
}
}
Test test = new Test();
{
test.ShowResult();
}
OUTPUT
Two Messageboxes
First displays: 20
Second displays: 9
If I didn't override the virtual method in the derived class the OUTPUT would be:
One Messageboxe ONLY
Displays: 20
From Documentation
When a virtual method is invoked, the run-time type of the object is checked for an overriding member. The overriding member in the most derived class is called, which might be the original member, if no derived class has overridden the member.
Upvotes: 1