【发布时间】:2010-12-07 08:41:40
【问题描述】:
有没有一种通用的方法可以将T 类型的单个项目传递给需要IEnumerable<T> 参数的方法?语言为 C#,框架版本 2.0。
目前我正在使用辅助方法(它是 .Net 2.0,所以我有一大堆类似于 LINQ 的投射/投影辅助方法),但这似乎很愚蠢:
public static class IEnumerableExt
{
// usage: IEnumerableExt.FromSingleItem(someObject);
public static IEnumerable<T> FromSingleItem<T>(T item)
{
yield return item;
}
}
其他方式当然是创建和填充List<T> 或Array 并传递它而不是IEnumerable<T>。
[编辑] 作为扩展方法,它可能被命名为:
public static class IEnumerableExt
{
// usage: someObject.SingleItemAsEnumerable();
public static IEnumerable<T> SingleItemAsEnumerable<T>(this T item)
{
yield return item;
}
}
我错过了什么吗?
[Edit2] 我们发现someObject.Yield()(正如@Peter 在下面的 cmets 中建议的那样)是此扩展方法的最佳名称,主要是为了简洁,所以这里与 XML 一起使用如果有人想抓住它,请发表评论:
public static class IEnumerableExt
{
/// <summary>
/// Wraps this object instance into an IEnumerable<T>
/// consisting of a single item.
/// </summary>
/// <typeparam name="T"> Type of the object. </typeparam>
/// <param name="item"> The instance that will be wrapped. </param>
/// <returns> An IEnumerable<T> consisting of a single item. </returns>
public static IEnumerable<T> Yield<T>(this T item)
{
yield return item;
}
}
【问题讨论】:
-
我将在扩展方法的主体中稍作修改:
if (item == null) yield break;现在您将停止传递 null 以及利用IEnumerable的(微不足道的)空对象模式. (foreach (var x in xs)处理空的xs就好了)。顺便说一句,这个函数是IEnumerable<T>列表 monad 的 monadic 单元,考虑到 Microsoft 的 monad love-fest,我很惊讶这样的东西一开始就没有在框架中。 -
对于扩展方法,你不应该将它命名为
AsEnumerable,因为一个名为already exists的内置扩展。 (当T实现IEnumerable,例如string。) -
把方法命名为
Yield怎么样?没有什么比简洁更重要的了。 -
此处的命名建议。 “SingleItemAsEnumerable”有点冗长。 “产量”描述的是实现而不是接口——这不好。为了更好的名字,我建议使用“AsSingleton”,它与行为的确切含义相对应。
-
我讨厌
left==null在这里检查。它破坏了代码的美感并阻止了代码的灵活性——如果有一天你需要生成一个可以为空的单例怎么办?我的意思是,new T[] { null }和new T[] {}不一样,总有一天你可能需要区分它们。
标签: c# .net generics ienumerable