内容简介:今天在写代码的过程都遇到了一个提示:截图如下:
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 引发的思考》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Thinking Recursively
Eric S. Roberts / Wiley / 1986-1-17 / USD 85.67
The process of solving large problems by breaking them down into smaller, more simple problems that have identical forms. Thinking Recursively: A small text to solve large problems. Concentrating on t......一起来看看 《Thinking Recursively》 这本书的介绍吧!