覆盖ToString()在抽象类(.net-core 3.1)中不起作用 [英] Override ToString() is not working in abstract class (.net-core 3.1)

查看:37
本文介绍了覆盖ToString()在抽象类(.net-core 3.1)中不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

将对象插入字符串中时(主要用于记录目的),需要将其显式序列化,否则得到的是:

When interpolating objects into strings (mainly for logging purposes), it needs to be explicitly serialized otherwise what you get is:

<ProjectName>.<Class>

或者就我而言

ConsoleApp1.Program+Person

因此,我制作了一个非常简单的控制台应用程序作为PoC来解决此问题.

So I made a very simple console application as a PoC to tackle this problem.

在此PoC中,我有一个抽象基类,该抽象基类仅使用 JsonSerializer 覆盖ToString方法,因此不需要在每次要登录/ConsoleWrite对象时都进行序列化.

In this PoC I have an abstract base class that only overrides ToString method with JsonSerializer, so I do not need to serialize every time I want to log/ConsoleWrite my object.

    public abstract class BaseModel
    {
        public override string ToString()
        {
            return JsonSerializer.Serialize(this);
        }
    }

这个抽象类应该由我所有的模型继承.这是整个控制台应用程序

This abstract class is supposed to be inherited by all my models. This is the whole console app

        static async Task Main(string[] args)
        {
            var a = new Person() { Name = "John", Lastname = "Doe" };
            Console.WriteLine($"Hi, {a}.");
            Console.ReadKey();
        }

        public class Person : BaseModel
        {
            public string Name { get; set; }
            public string Lastname { get; set; }
        }

运行ConsoleWrites上方的代码

Running the code above ConsoleWrites

Hi, {}.

为什么它是空的?

当我以抽象方法在 this 上放置一个Quickwatch时,我可以看到属性已正确填充.

When I put a Quickwatch on this in the abstract method I can see that the properties are populated properly.

为什么会这样?

推荐答案

您使用的.NET Core json序列化器方法是通用的,如下所示:

The .NET Core json serializer method you used is generic, like this:

public static string Serialize<TValue> (TValue value,
    System.Text.Json.JsonSerializerOptions options = default);

根据设计,它在序列化时仅考虑 TValue 中的属性,并且由于您是使用 this 从抽象类中对其进行调用的,因此当然可以属于抽象类类型,它仅考虑抽象类中的属性.

By design, it only considers the properties in TValue when it serializes, and since you called it from your abstract class, with this, which of course will then be of the abstract class type, it only considers properties in the abstract class.

基本上,您的电话被推断为

Basically your call is inferred to be

return JsonSerializer.Serialize<BaseModel>(this);

幸运的是,它很容易修复,只需切换到调用非泛型方法即可:

Fortunately, it is easy to fix, simply switch to calling the non-generic method:

return JsonSerializer.Serialize(this, GetType());

现在,它使用有关您实际上要调用的类型的运行时信息,而不是抽象类,并且应该正确地序列化后代类型的属性.

Now it uses runtime information about which type you're actually calling it about instead of the abstract class, and should correctly serialize properties from your descendant type.

这篇关于覆盖ToString()在抽象类(.net-core 3.1)中不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆