创建 IEnumerable最简单、最紧凑的方法是什么?或 ICollection

发布于 2024-08-06 02:17:47 字数 460 浏览 8 评论 0原文

因此,很多时候我们有一个接受 IEnumerable 或 ICollection 作为参数的函数。如果我们有单个项目,但没有集合来保存它们,则必须在将它们传递给函数之前创建一个集合,例如:

T o1, o2, o3;
Foo(new T[] { o1, o2, o3 });

我总是创建一个数组或列表,就像我在上一个示例中所做的那样。但我想知道,是否有更优雅的方式来创建所需的 IEnumerable 或 ICollection?

如果能够做到这一点,那就太酷了:

Foo({ o1, o2, o3 });

编译器将创建尽可能抽象的集合,以满足 IEnumerable 或 ICollection 的需求(取决于函数接受哪一个)。

无论如何,如何将 o1、o2 和 o3 传递给 IEnumerable 或 ICollection 参数?

So, many times we have a function that accepts an IEnumerable or ICollection as a parameter. In cases where we have single items, but no collection to hold them, we must create a collection before passing them to the function, like:

T o1, o2, o3;
Foo(new T[] { o1, o2, o3 });

I've always created an array or a list, like I've done in the last example. But I wonder, is there a more elegant way to create the required IEnumerable or ICollection?

It would be quite cool, if one could do this:

Foo({ o1, o2, o3 });

And the compiler would create the most abstract possible collection that would satisfy the needs of IEnumerable or ICollection (depending on which one the function accepts).

Anyhow, how you would pass o1, o2 and o3 to an IEnumerable or ICollection parameters?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

柠栀 2024-08-13 02:17:47

当前版本的C# (3) 支持无显式类型的表示法,即

Foo(new [] { o1, o2, o3 })

创建数组。还有 Linq 的 Enumerable.Range 来创建连续的数字范围。其他一切都必须实施。本着 Java 的精神:

public static IEnumerable<T> AsList<T>(params T[] values) {
    return values;
}

这样调用:

Foo(Enumerable.AsList(o1, o2, o3));

The current version of C# (3) supports a notation without explicit type, i.e.

Foo(new [] { o1, o2, o3 })

to create an array. There’s also Linq’s Enumerable.Range to create a continuous range of numbers. Everything else has to be implemented. In the spirit of Java:

public static IEnumerable<T> AsList<T>(params T[] values) {
    return values;
}

to be called like this:

Foo(Enumerable.AsList(o1, o2, o3));
庆幸我还是我 2024-08-13 02:17:47

有时我使用带有“params”参数的方法。

Foo(params T[] ts)

如果我对 IEnumerable 死心塌地,我只需将该方法委托给需要 IEnumerable 的方法即可。

Foo(params T[] ts) { Foo(ts.AsEnumerable()); }

你必须调用 AsEnumerable 否则你将递归。

Sometimes I've used a method with a "params" argument.

Foo(params T[] ts)

And if I'm dead set on IEnumerable I just have that method delegate to the one that wants IEnumerable.

Foo(params T[] ts) { Foo(ts.AsEnumerable()); }

You have to call AsEnumerable or you're going to recurse.

忆梦 2024-08-13 02:17:47

假设 Foo 需要 IEnumerable,您可以利用类型推断并执行以下操作:

T o1, o2, o3;
Foo(new []{o1, o2, o3});

Assuming Foo expects an IEnumerable<T>, you can take advantage of type inference and do:

T o1, o2, o3;
Foo(new []{o1, o2, o3});
风和你 2024-08-13 02:17:47

创建一个数组并传递可能是当前版本的 C# 中实现此目的最简单/最优雅的方法。您可以利用隐式数组类型(即 new[] { ... }),但仅此而已。

我怀疑您确实在寻找与此 F# 语法等效的 C# 语法:

let foo = seq [ o1; o2; o3 ]

它生成一个 IEnumerable ,它将迭代指定的元素(“Seq”实际上是“IEnumerable”的 F# 别名,尽管 F# 内置了对它们的支持。)

不幸的是,因为这是一个很大程度上是功能性的概念,没有 C# 的等效概念 - 尽管谁知道它何时会被添加,因为 C# 变得越来越功能化。

Creating an array and passing that is probably the simplest/most elegant way to accomplish this in the current version of C#. You can take advantage of implicit array typing (i.e. new[] { ... }, but that's as far as it goes.

I suspect you're really looking for the C# equivalent of this F# syntax:

let foo = seq [ o1; o2; o3 ]

which generates an IEnumerable<T> that will iterate over the specified elements. ('Seq' is actually the F# alias for 'IEnumerable`, though F# has built-in support for them.)

Unfortunately, since this is a largely functional notion, there is no C# equivalent - though who knows when it will be added, as C# becomes more and more functional.

绮筵 2024-08-13 02:17:47

如果您有一个将数组作为最后一个参数的方法,则标记该参数 params 可能是有意义的。这可以让您像这样调用该方法:

Foo(o1, o2, o3);

我发现这在为 Foo() 编写单元测试时特别有用,因为通常在单元测试中我的参数是像这样分开的,而不是在数组中。

如果 Foo() 的重载不接受该位置的数组,我建议不要这样做,因为它很快就会变得混乱。

我确实希望 C# 语言允许 IList 使用 params

void Foo(params IList<T> ts) { ... }

If you have a method that takes an array as its last parameter, it may make sense to mark that parameter params. This lets you call the method like this:

Foo(o1, o2, o3);

I find this particularly helpful when writing a unit test for Foo(), because often in a unit test my parameters are separate like this, instead of in an array.

I advise against doing this if there is an overload of Foo() that doesn't take an array in that position, because it can get confusing quickly.

I do wish that the C# language allowed params for IList<T>:

void Foo(params IList<T> ts) { ... }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文