【发布时间】:2010-09-15 10:08:45
【问题描述】:
为什么会产生编译错误:
class X { public void Add(string str) { Console.WriteLine(str); } }
static class Program
{
static void Main()
{
// error CS1922: Cannot initialize type 'X' with a collection initializer
// because it does not implement 'System.Collections.IEnumerable'
var x = new X { "string" };
}
}
但事实并非如此:
class X : IEnumerable
{
public void Add(string str) { Console.WriteLine(str); }
IEnumerator IEnumerable.GetEnumerator()
{
// Try to blow up horribly!
throw new NotImplementedException();
}
}
static class Program
{
static void Main()
{
// prints “string” and doesn’t throw
var x = new X { "string" };
}
}
将集合初始值设定项(用于调用 Add 方法的语法糖)限制为实现接口的类的原因是什么,该接口具有Add 方法和哪个没用?
【问题讨论】:
-
C# 中有些东西我只是不明白。这是其中之一。另一个是
foreach。 -
@leppie:你对 foreach 没有“了解”什么?
-
@Jon Skeet:我认为 leppie 指的是编译器只需要一个方法的存在而不需要一个特定的接口,这是一种强类型语言中的鸭子类型行为。
-
@0xA3:这主要是因为 C# 1 中缺少泛型。这种鸭子类型允许使用值类型的强类型迭代器无需装箱。我怀疑如果它以泛型开头,它就不会出现在 C# 中,尽管它仍然用于避免在
List<T>上使用 foreach 时对迭代器进行装箱。 -
@Jon Skeet:它的作用超出了人们的预期。我确实“明白”了它,我只是不明白为什么。但正如你所说,这可能与泛型有关。
标签: c# syntax language-design