C# 将单个项目作为 IEnumerable<T> 传递
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1577822/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Passing a single item as IEnumerable<T>
提问by Groo
Is there a common way to pass a single item of type T
to a method which expects an IEnumerable<T>
parameter? Language is C#, framework version 2.0.
有没有一种通用的方法可以将单个类型的项目传递给T
需要IEnumerable<T>
参数的方法 ?语言为 C#,框架版本 2.0。
Currently I am using a helper method (it's .Net 2.0, so I have a whole bunch of casting/projecting helper methods similar to LINQ), but this just seems silly:
目前我正在使用一个辅助方法(它是 .Net 2.0,所以我有一大堆类似于 LINQ 的转换/投影辅助方法),但这似乎很愚蠢:
public static class IEnumerableExt
{
// usage: IEnumerableExt.FromSingleItem(someObject);
public static IEnumerable<T> FromSingleItem<T>(T item)
{
yield return item;
}
}
Other way would of course be to create and populate a List<T>
or an Array
and pass it instead of IEnumerable<T>
.
其他方式当然是创建和填充 aList<T>
或 anArray
并传递它而不是IEnumerable<T>
.
[Edit]As an extension method it might be named:
[编辑]作为一个扩展方法,它可能被命名为:
public static class IEnumerableExt
{
// usage: someObject.SingleItemAsEnumerable();
public static IEnumerable<T> SingleItemAsEnumerable<T>(this T item)
{
yield return item;
}
}
Am I missing something here?
我在这里错过了什么吗?
[Edit2]We found someObject.Yield()
(as @Peter suggested in the comments below) to be the best name for this extension method, mainly for brevity, so here it is along with the XML comment if anyone wants to grab it:
[Edit2]我们发现someObject.Yield()
(正如@Peter 在下面的评论中建议的那样)是这个扩展方法的最佳名称,主要是为了简洁,所以如果有人想抓住它,这里有 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;
}
}
采纳答案by Jon Skeet
Your helper method is the cleanest way to do it, IMO. If you pass in a list or an array, then an unscrupulous piece of code could cast it and change the contents, leading to odd behaviour in some situations. You could use a read-only collection, but that's likely to involve even more wrapping. I think your solution is as neat as it gets.
你的辅助方法是最干净的方法,IMO。如果您传入一个列表或一个数组,那么一段不道德的代码可能会对其进行转换并更改内容,从而在某些情况下导致奇怪的行为。您可以使用只读集合,但这可能涉及更多的包装。我认为您的解决方案非常简洁。
回答by Mario F
Well, if the method expects an IEnumerable
you've got to pass something that is a list, even if it contains one element only.
好吧,如果该方法需要一个,IEnumerable
你必须传递一个列表,即使它只包含一个元素。
passing
通过
new[] { item }
as the argument should be enough I think
因为论点应该足够了,我认为
回答by FacticiusVir
The easiest way I'd say would be new T[]{item};
; there's no syntax to do this. The closest equivalent that I can think of is the params
keyword, but of course that requires you to have access to the method definition and is only usable with arrays.
我想说的最简单的方法是new T[]{item};
;没有语法可以做到这一点。我能想到的最接近的等价物是params
关键字,但当然这要求您能够访问方法定义并且只能用于数组。
回答by Dаn
In C# 3 (I know you said 2), you can write a generic extension method which might make the syntax a little more acceptable:
在 C# 3(我知道你说的是 2)中,你可以编写一个通用的扩展方法,这可能会使语法更容易接受:
static class IEnumerableExtensions
{
public static IEnumerable<T> ToEnumerable<T>(this T item)
{
yield return item;
}
}
client code is then item.ToEnumerable()
.
客户代码是那么item.ToEnumerable()
。
回答by Joshua Starner
I'm kind of surprised that no one suggested a new overload of the method with an argument of type T to simplify the client API.
我有点惊讶,没有人建议使用 T 类型的参数对该方法进行新的重载以简化客户端 API。
public void DoSomething<T>(IEnumerable<T> list)
{
// Do Something
}
public void DoSomething<T>(T item)
{
DoSomething(new T[] { item });
}
Now your client code can just do this:
现在您的客户端代码可以这样做:
MyItem item = new MyItem();
Obj.DoSomething(item);
or with a list:
或使用列表:
List<MyItem> itemList = new List<MyItem>();
Obj.DoSomething(itemList);
回答by erikkallen
Either (as has previously been said)
要么(如前所述)
MyMethodThatExpectsAnIEnumerable(new[] { myObject });
or
或者
MyMethodThatExpectsAnIEnumerable(Enumerable.Repeat(myObject, 1));
As a side note, the last version can also be nice if you want an empty list of an anonymous object, e.g.
作为旁注,如果你想要一个匿名对象的空列表,最后一个版本也可以很好,例如
var x = MyMethodThatExpectsAnIEnumerable(Enumerable.Repeat(new { a = 0, b = "x" }, 0));
回答by luksan
In C# 3.0 you can utilize the System.Linq.Enumerable class:
在 C# 3.0 中,您可以使用 System.Linq.Enumerable 类:
// using System.Linq
Enumerable.Repeat(item, 1);
This will create a new IEnumerable that only contains your item.
这将创建一个仅包含您的项目的新 IEnumerable。
回答by teppicymon
As I have just found, and seen that user LukeH suggested too, a nice simple way of doing this is as follows:
正如我刚刚发现的,并且看到用户 LukeH 也建议,一个很好的简单方法如下:
public static void PerformAction(params YourType[] items)
{
// Forward call to IEnumerable overload
PerformAction(items.AsEnumerable());
}
public static void PerformAction(IEnumerable<YourType> items)
{
foreach (YourType item in items)
{
// Do stuff
}
}
This pattern will allow you to call the same functionality in a multitude of ways: a single item; multiple items (comma-separated); an array; a list; an enumeration, etc.
这种模式将允许您以多种方式调用相同的功能:单个项目;多个项目(逗号分隔);数组; 一个列表; 枚举等
I'm not 100% sure on the efficiency of using the AsEnumerable method though, but it does work a treat.
虽然我不是 100% 确定使用 AsEnumerable 方法的效率,但它确实有效。
Update: The AsEnumerable function looks pretty efficient! (reference)
更新:AsEnumerable 函数看起来非常高效!(参考)
回答by Ken Lange
This may not be any better but it's kind of cool:
这可能不会更好,但它有点酷:
Enumerable.Range(0, 1).Select(i => item);
回答by Ruben Bartelink
IanGhas a good post on the topic, suggesting EnumerableFrom()
as the name (and mentions that Haskell and Rx call it Return
). IIRC F# calls it Return too. F#'s Seq
calls the operator singleton<'T>
.
IanG有一篇关于该主题的好帖子,建议EnumerableFrom()
使用该名称(并提到 Haskell 和 Rx 称其为Return
)。IIRC F# 也将其称为 Return。F#Seq
调用 operatorsingleton<'T>
。
Tempting if you're prepared to be C#-centric is to call it Yield
[alluding to the yield return
involved in realizing it].
如果您准备好以 C# 为中心,那么可以称之为Yield
[暗指yield return
实现它的过程]。
If you're interested in the perf aspects of it, James Michael Hare has a returning zero or one items posttoo which is well worth a scan.
如果您对它的性能方面感兴趣,James Michael Hare 也有返回零或一个项目的帖子,非常值得一看。