考虑:
// 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());
}
}
Run Code Online (Sandbox Code Playgroud)
似乎 baseToString不是继承的,编译器仍然自动生成派生的Tostring
这是为什么 ?有什么好办法吗?
小智 23
有一条评论为我解决了这个问题。Sean 说,如果您添加sealed到该方法中,它会阻止编译器合成该ToString方法,如下所示:
public sealed override string ToString() => Value;
Run Code Online (Sandbox Code Playgroud)
ToString请注意,C# 10 中引入了密封覆盖的功能。
该record声明取代了继承的ToString(). 这在新增功能描述中进行了解释:
编译器综合了两种支持打印输出的方法:ToString() 覆盖和 PrintMembers。
不考虑基类(也是 a record)具有ToString覆盖的事实。从技术上讲所有类型继承ToString()从object,所以代码生成器record的类型并不在基本类型寻找一个继承覆盖,否则编译器生成的ToString将永远不会被创建。
(您可能会争辩说应该保留ToString继承record类型中的 a ,但这不是该功能的设计方式)。
但是如果记录类型有一个被覆盖的ToString(),那么编译器不会生成一个:
如果记录类型具有与任何合成方法的签名匹配的方法,则编译器不会合成该方法。
您可以定义一个看似多余的覆盖:
public override string ToString() => base.ToString();
Run Code Online (Sandbox Code Playgroud)
这应该可以防止编译器ToString由于record声明而自动生成覆盖。
| 归档时间: |
|
| 查看次数: |
1081 次 |
| 最近记录: |