内容简介:今天在写代码的过程都遇到了一个提示:截图如下:
1. 概述
今天在写代码的过程都遇到了一个提示:
redundant 'object.tostring()' call
截图如下:
IDE的意思是可以去除 ToString() 的调用, 为什么会有这个提示呢?
查看 MakeCallInfo 这个类发现覆写了 ToString() 方法. 那么是不是只要有 ToString() 方法就会有这个提示呢?
2. 测试
2.1 不添加 ToString() 方法
编写如下代码:
namespace DevConsoleApp {
class Program {
static void Main(string[] args) {
Person p = new Person();
p.Name = "张三";
p.Age = 13;
Console.WriteLine(p);
Console.WriteLine(p.ToString());
Console.WriteLine($"this is {p}");
Console.WriteLine($"this is {p.ToString()}");
Console.ReadKey();
}
}
class Person {
public string Name;
public int Age;
}
}
Person 类没有继承覆写 ToString() 方法, 在 Main 方法中的四种写法中, IDE在最后的一种写法中做了提示:
因为 Person 类没有 ToString() 方法, 实际调用的是 object.ToString() 方法, 所以这里会提示.
运行结果如下:
2. 添加 ToString() 方法
修改代码如下:
namespace DevConsoleApp {
class Program {
static void Main(string[] args) {
Person p = new Person();
p.Name = "张三";
p.Age = 13;
Console.WriteLine(p);
Console.WriteLine(p.ToString());
Console.WriteLine($"this is {p}");
Console.WriteLine($"this is {p.ToString()}");
Console.ReadKey();
}
}
class Person {
public string Name;
public int Age;
public string ToString() {
return $"{nameof(Name)}: {Name}, {nameof(Age)}: {Age}";
}
}
}
这种修改以后, IDE 在输出的时候没有再提示 redundant 'object.tostring()' call , 截图如下:
但是, 此时的 ToString() 方法会有提示:
因为新添加的方法和父类的方法同名, 所以这里会提示让你确认这是覆写的父类方法还是新增的方法.
如果不按照它的提示, 直接运行会怎样?
运行结果可以看出, 第一个输出不是 ToString() 的格式字符串, 这说明编译器默认该方法为 新方法, 和 添加 new 关键字一致.
2.3 添加覆写方法
将2.2 的 new 改为 override , 即覆写父类的 ToString() 方法:
namespace DevConsoleApp {
class Program {
static void Main(string[] args) {
Person p = new Person();
p.Name = "张三";
p.Age = 13;
Console.WriteLine(p);
Console.WriteLine(p.ToString());
Console.WriteLine($"this is {p}");
Console.WriteLine($"this is {p.ToString()}");
Console.ReadKey();
}
}
class Person {
public string Name;
public int Age;
public override string ToString() {
return $"{nameof(Name)}: {Name}, {nameof(Age)}: {Age}";
}
}
}
此时, 输出部分 IDE 扔会提示 redundant 'object.tostring()' call , :
运行结果呢?
从输出结果看, 第一种和第二种输出结果是一致的. 但是为什么第二种不提示 第四种提示呢?
3. 查看源码
第一种输出 Console.WriteLine(p); 其代码实现如下:
public static void WriteLine(object value)
{
Console.Out.WriteLine(value);
}
public virtual void WriteLine(object value)
{
if (value == null)
this.WriteLine();
else if (value is IFormattable formattable)
this.WriteLine(formattable.ToString((string) null, this.FormatProvider));
else
this.WriteLine(value.ToString());
}
其实最终还是调用了 ToString() 方法.
剩下的输出其实都是调用了 Console.WriteLine(string value) 方法, 如下:
public static void WriteLine(string value)
{
Console.Out.WriteLine(value);
}
public virtual void WriteLine(string value)
{
if (value == null)
{
this.WriteLine();
}
else
{
int length1 = value.Length;
int length2 = this.CoreNewLine.Length;
char[] chArray = new char[length1 + length2];
value.CopyTo(0, chArray, 0, length1);
switch (length2)
{
case 1:
chArray[length1] = this.CoreNewLine[0];
break;
case 2:
chArray[length1] = this.CoreNewLine[0];
chArray[length1 + 1] = this.CoreNewLine[1];
break;
default:
Buffer.InternalBlockCopy((Array) this.CoreNewLine, 0, (Array) chArray, length1 * 2, length2 * 2);
break;
}
this.Write(chArray, 0, length1 + length2);
}
}
第二种输出格式 是在传参给 WriteLine 方法时, 已经进行了格式化处理, 传入的就是一个 string字符串. 即:
- 如果不带
ToString方法, 调用的是Console.WriteLine(object o)方法 - 如果带
ToString()方法, 调用的是Console.WriteLine(string value)方法
所以第二种输出格式不会提示 Redundant 'object.tostring()' call .
而第三四种输出 传入的参数是一个格式化的 string字符串, 内插值字符串.
对于内插值字符串, 官方文档: $ - 字符串内插 - C# 参考 | Microsoft Docs 的一段说明如下:
隐式转换和指定 IFormatProvider 实现的方式
内插字符串有 3 种隐式转换:
- 将内插字符串转换为 String 实例,该类例是内插字符串的解析结果,其中内插表达式项被替换为结果的格式设置正确的字符串表示形式。 此转换使用 CurrentCulture 设置表达式结果的格式。
-
将内插字符串转换为表示复合格式字符串的 FormattableString 实例,同时也将表达式结果格式化。 这允许通过单个 FormattableString 实例创建多个包含区域性特定内容的结果字符串。 要执行此操作,请调用以下方法之一:
- ToString() 重载,生成 CurrentCulture 的结果字符串。
- Invariant 方法,生成 InvariantCulture 的结果字符串。
- ToString(IFormatProvider) 方法,生成特定区域性的结果字符串。
你还可使用 ToString(IFormatProvider) 方法,以提供支持自定义格式设置的 IFormatProvider 接口的用户定义实现。 有关详细信息,请参阅 在 .NET 中设置类型格式 一文中的 使用 ICustomFormatter 进行自定义格式设置 部分。
- 将内插字符串转换为 IFormattable 实例,使用此实例也可通过单个 IFormattable 实例创建多个包含区域性特定内容的结果字符串。
意思就是说, 内插值字符串直接传入对象的引用 会实际调用其 ToString() 方法, 所以会提示 Redundant 'object.tostring()' call
4. 总结
从上述分析中看出, 如果我们要覆写父类的方法就必须带上 override 关键字, 否则编译器会认为你写的是一个新的方法,即默认为 new 关键字.
以上所述就是小编给大家介绍的《Redundant 'object.tostring()' call 引发的思考》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
C++ Primer 中文版(第 5 版)
[美] Stanley B. Lippman、[美] Josée Lajoie、[美] Barbara E. Moo / 王刚、杨巨峰 / 电子工业出版社 / 2013-9-1 / CNY 128.00
这本久负盛名的 C++经典教程,时隔八年之久,终迎来史无前例的重大升级。除令全球无数程序员从中受益,甚至为之迷醉的——C++ 大师 Stanley B. Lippman 的丰富实践经验,C++标准委员会原负责人 Josée Lajoie 对C++标准的深入理解,以及C++ 先驱 Barbara E. Moo 在 C++教学方面的真知灼见外,更是基于全新的 C++11标准进行了全面而彻底的内容更新。......一起来看看 《C++ Primer 中文版(第 5 版)》 这本书的介绍吧!
RGB转16进制工具
RGB HEX 互转工具
正则表达式在线测试
正则表达式在线测试