重构时我相信编译器,但是偶然发现了一些奇怪的东西。
public static void Main()
{
Console.WriteLine(List() + "wtf"); // no compilation error
}
public static IEnumerable<string> List() {
yield return "abc";
yield return "xyz";
}
谁能解释编译器接受此请求的原因是什么?
PS:既然您知道它不会引发异常,请猜测控制台将输出什么内容。答案在这里:https://dotnetfiddle.net/9nz8Bl
答案 0 :(得分:3)
无需猜测...
当您执行someValueOrObject + string
并且 someValueOrObject 不能隐式转换为字符串时,将在 someValueOrObject上调用 ToString()方法以获得其字符串表示形式(等效于someValueOrObject.ToString() + string
)。
ToString()
是由System.Object
类实现的虚拟方法(.NET中的任何其他类型都从该类派生exceptions notwithstanding)。除非被覆盖,否则它的默认行为是返回被调用实例的(完全限定的)类型名称。
为了更好地理解这一点,您可能需要运行以下示例:
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
var l = List();
Console.WriteLine("Type of enumerable returned by List(): " + l.GetType().FullName);
Console.WriteLine(l + "wtf");
}
public static IEnumerable<string> List() {
yield return "abc";
yield return "xyz";
}
}
(https://dotnetfiddle.net/H0hl4O)
假设迭代器方法 List()返回的由编译器生成的可枚举对象的类型名称为“ Program + d__0
”,则此示例将生成以下输出:
List()返回的可枚举类型:Program +
d__0
程序+d__0wtf