我在open source project中找到了以下方法:
static IEnumerable<T> Cat<T>(T t) {
yield return t;
}
据我了解,它只会返回包含IEnumerable<T>
的{{1}}。如果我是对的,那它就等同于t
,在这里使用return new List<T>{t};
的目的/优势是什么?如果我错了,我会错过什么?
答案 0 :(得分:5)
这只是一个包含单个元素(t
)的可枚举类型。实际上,你是对的 - 它实际上非常类似于只用一个元素返回一个新的List<T>
,或者用一个元素返回一个新的数组等。
主要区别在于返回的类型实际上不是List<T>
或数组 - 它将是编译器生成的类型。例如,您将无法将结果转换为列表并添加元素。在实际应用中,它的行为与返回你所描述的新List<T>
相同。
除了开发人员可能更喜欢这种语法之外,可能没有真正的优势。我怀疑可能用于允许单个元素与API的其他部分一起工作,期望传递IEnumerable<T>
,尽管方法名称有点不尽如人意,IMO。
答案 1 :(得分:3)
返回实际集合和使用yield
之间的区别只是您返回的对象的类型。
如果返回任何实现IEnumerable<T>
的集合,则返回的对象的实际类型将是该类型。例如,如果您返回List<T>
,则返回的引用将是IEnumerable<T>
类型,但引用所指向的对象的实际类型是List<T>
的实例。
如果使用yield
,编译器将创建一个没有已知名称的枚举器对象。返回的引用类型也将是IEnumerable<T>
,但引用所指向的对象的实际类型将是编译器创建的类型。
例如,获取为整数创建的枚举数类型的名称:
Console.WriteLine(Cat<int>(42).GetType().Name);
将显示编译器使用的内部名称,例如我从代码中获得的结果:
<Cat>d__5`1
如果该函数将返回List<int>
,则该类型将显示为:
List`1
让编译器为此创建一个枚举器的动机可能只是它比这样的东西短:
static IEnumerable<T> Cat<T>(T t) {
List<T> list = new List<T>(1);
list.Add(t);
return list;
}
(您可以在较新版本的C#中使用快捷方式将其写得更短,但仍然不如yield
那么短。)
当类型是集合时,您可以将引用转换为实际类型并更改集合中的值:
IEnumerable<int> ienum = Cat<int>(42);
((List<int>)ienum)[0] = 1337;
foreach (int value in ienum) {
Console.WriteLine(value);
}
将输出:
1337
答案 2 :(得分:0)
此函数将单个项目转换为可枚举项目 如果你有一个可枚举的,并且你想附加一个项目,例如:
IEnumerable<someType> Columns;
var headers = String.Join(",", Columns.Select(c => c.Name).Concat(new string[] { "Last Column" }));
编写
更好 var headers = String.Join(",", Columns.Select(c => c.Name).Concat(Cat("Last Column")));