C#9.0记录-不继承ToString

问题描述

考虑:

// 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());
  }
}

sharplab

似乎没有继承基数ToString,并且编译器仍会自动生成派生的Tostring

那是为什么?有什么好办法吗?

解决方法

record声明取代了继承的ToString()What's New说明中对此进行了解释:

编译器综合了两种支持打印输出的方法:ToString()覆盖和PrintMembers。

不考虑基类(也是record)具有ToString覆盖的事实。从技术上讲,所有类型都从ToString()继承object,因此record类型的代码生成器不会查看继承的替代的基本类型,否则由编译器生成ToString从不创建

(您可能会争辩说,应该保留继承的ToString类型的record,但这不是设计功能的方式。)

但是,如果记录类型具有覆盖的ToString(),则编译器不会生成一个:

如果记录类型的方法与任何合成方法的签名都匹配,则编译器不会合成该方法。

您可以定义看似多余的替代:

公共替代字符串ToString()=> base.ToString();

这应该防止编译器基于ToString声明自动生成record

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...