Override 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 方法,所以我不需要每次想记录/控制台写入我的对象时都进行序列化.
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屋!