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

查看:15
本文介绍了Override 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 方法,所以我不需要每次想记录/控制台写入我的对象时都进行序列化.

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, {}.

为什么是空的?

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

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.

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

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