Search code examples
c#inheritancevirtualjson-serialization

If a function uses "this", does invoking the function from a child class include the properties of the child class?


I create a class that includes a function to serialize itself to a JSON string using the "this" keyword, this class is then inherited by a child class.

public class Parent
{
    int a { get; set; }

    public ToJsonString()
    {
        return JsonSerializer.Serialize(this);
    }
}

public class Child : Parent
{
    int b { get; set; }
}

If an instance of the child class then invokes the ToJsonString() function, will the returned string include the properties from the child class, or only those from the parent class?

Child instance = new Child();
string serialized = instance.ToJsonString();

Solution

  • This can easily be tested see (code below).

    The original version of ToJsonString has a Parent parameter and only serialises the Parent properties. This can be remedied by overriding ToJsonString in Child with an identical implementation:

    using System.Text.Json;
    
    
    Console.WriteLine($"Using parent version of 'ToJsonString': {new Child().BaseToJsonString()}");
    Console.WriteLine($"Using child version of 'ToJsonString': {new Child().ToJsonString()}");
    Console.WriteLine($"Using better version of 'ToJsonString': {new Child().BetterToJsonString()}");
    
    
    public class Parent
    {
        public int A { get; set; } = 1;
    
        public string BaseToJsonString()
        {
            return JsonSerializer.Serialize(this);
        }
        public virtual string ToJsonString()
        {
            return JsonSerializer.Serialize(this);
        }
        public string BetterToJsonString()
        {
            return JsonSerializer.Serialize(this, GetType());
        }
    }
    
    public class Child : Parent
    {
        public int B { get; set; } = 2;
    
        public override string ToJsonString()
        {
            return JsonSerializer.Serialize(this);
        }
    }
    

    This yields:

    Using parent version of 'ToJsonString': {"A":1}
    Using child version of 'ToJsonString': {"B":2,"A":1}
    Using better version of 'ToJsonString': {"B":2,"A":1}

    Edit:

    As Petrusion correctly points out, another - much simpler - solution would be to force the Serialize method to use the actual runtime type (see BetterToJsonStringmethod above).