问题描述
考虑:
// the ratioale for Wrapper is that it has a Json serializer that
// serialize through Field (not included in this example)
record Wrapper<T> where T : notnull {
protected Wrapper(T field) => Field = field;
protected Wrapper(Wrapper<T> wrapper) => Field = wrapper.Field;
protected readonly T Field;
public override string ToString() => Field.ToString() ?? "";
}
record MyRec : Wrapper<string> {
public MyRec(string s) : base(s) {}
}
public static class Program {
public static void Main(string[] args) {
var r = new MyRec("hello");
Console.WriteLine(r.ToString());
}
}
似乎没有继承基数ToString
,并且编译器仍会自动生成派生的Tostring
那是为什么?有什么好办法吗?
解决方法
record
声明取代了继承的ToString()
。 What's New说明中对此进行了解释:
编译器综合了两种支持打印输出的方法:ToString()覆盖和PrintMembers。
不考虑基类(也是record
)具有ToString
覆盖的事实。从技术上讲,所有类型都从ToString()
继承object
,因此record
类型的代码生成器不会查看继承的替代的基本类型,否则由编译器生成ToString
将从不创建。
(您可能会争辩说,应该保留继承的ToString
类型的record
,但这不是设计功能的方式。)
但是,如果记录类型具有覆盖的ToString()
,则编译器不会生成一个:
如果记录类型的方法与任何合成方法的签名都匹配,则编译器不会合成该方法。
您可以定义看似多余的替代:
公共替代字符串ToString()=> base.ToString();
这应该防止编译器基于ToString
声明自动生成record
。