覆盖ToString()在抽象类(.net-core 3.1)中不起作用 [英] Override ToString() is not working in abstract class (.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屋!