-3

一些上下文:我想编写一个类,其中将事物添加到集合的主要方法是通过名为 Add (或类似名称)的方法(或方法)。所以看起来最好的签名是 params object[]。在内部,这个函数必须切换/if-else 它可以接受的所有类型。所以,最初它可以接受这个 object[] 数组,但我可能希望它也接受 object[][] 和 object[][][] 等,然后方法/函数可以在内部变平,所以用户在调用此函数之前不需要这样做。

所以...

是否可以编写一个函数来接受一种对象的各种级别的列表类型? 作为一个附带问题,在设计类的接口时,接受object[]orIEnumerable<object>或哪个更好params object[](编辑:从这个问题中脱颖而出,因为已经有足够的事情发生了。)

例如,我正在考虑一个函数,它同时接受/全部object[], IEumerable<object>,并可能进一步嵌套,例如:IEnumerable<IEnumerable<object>>, object[][](以及 on、on 和 on 等)。

这可能吗?

4

4 回答 4

16

您会注意到List<T>该类本身具有采用 T 的 Add 方法和采用 T 序列的 AddRange 方法。出于两个原因,我们不会尝试重载 Add 来同时执行这两种操作。首先,因为添加一个东西和添加一堆东西在逻辑上是不同的,其次,因为它使重载解析变得非常复杂。

如果您想要一个采用 T 序列的方法,则编写一个采用 T 序列的方法。如果调用者有一个序列序列,则将其展平;不要试图代表他们猜测如何有效地做到这一点。

哪个更好:接受object[]or IEnumerable<object>or params object[]?

我们到底应该怎么知道?我们不是调用该方法的人。你应该问的人是要编写代码来调用你的方法的人。

于 2012-01-09T19:12:38.040 回答
2

一种选择是只创建一个函数,然后根据需要多次重载它。您可以使重载函数调用“基”函数。

DoWork(params object[] args)
{
  //do the actual work
}

DoWork(IEnumerable<object> args)
{
  DoWork(args.ToArray());
}

//etc etc
于 2012-01-09T19:06:34.847 回答
1

这实际上取决于列表类型的含义。如果您明确表示,那么您可以有一个接受的方法IList<T>。如果您想将数组混入其中,那么您真的应该接受IEnumerable<T>. 除非你需要修改它,在这种情况下数组不会真正起作用,所以你可以接受ICollection<T>.

于 2012-01-09T19:06:39.240 回答
1

对一个函数进行两次重载,一个接受IEnumerable<T>,一个接受params T[]。通过调用前者来实现后者。忘记嵌套,LINQ 可以使用SelectMany.

于 2012-01-09T19:05:02.210 回答