Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
有没有更好的方法来编写接受多种类型的C#函数?_C#_Function Declaration_Generic Collections - Fatal编程技术网

有没有更好的方法来编写接受多种类型的C#函数?

有没有更好的方法来编写接受多种类型的C#函数?,c#,function-declaration,generic-collections,C#,Function Declaration,Generic Collections,一些上下文:我想编写一个类,其中向集合添加内容的主要方法是通过一个名为Add(或类似名称)的方法(或多个方法)。所以看起来最好的签名是params object[]。在内部,这个函数必须切换/if-else它可以接受的所有类型。因此,最初它可以接受这个object[]数组,但我可能希望看到它也接受object[]]和object[][]等,然后方法/函数可以在内部展开,因此用户在调用此函数之前不需要这样做 DoWork(params object[] args) { //do the act

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

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

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

//etc etc
所以

是否可以编写一个函数,为单一类型的对象接受不同级别的列表类型?作为附带问题,在设计类的接口时,接受
对象[]
IEnumerable
参数对象[]
哪个更好?(编辑:从问题中删除,因为已经有足够的内容了。)

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


这可能吗?

对一个函数进行两个重载,一个接受
IEnumerable
,另一个接受
参数T[]
。通过调用前者来实现后者。忘记嵌套,LINQ可以轻松地使用展开集合。

一个选项是只制作一个函数,然后根据需要多次重载它。您可以让重载函数调用“base”函数

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

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

//etc etc
DoWork(参数对象[]args)
{
//做实际工作
}
道工(IEnumerable args)
{
道具(args.ToArray());
}
//等等

这实际上取决于列表类型的含义。如果您明确表示,那么您可以有一个接受的方法。如果您想将数组加入到混合中,那么您应该真正接受
IEnumerable
。除非您需要修改它,否则在这种情况下数组将无法真正工作,因此您可以接受
ICollection

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

如果你想要一个取T序列的方法,那么写一个取T序列的方法。如果调用者有一个序列,让他们把它展平;不要试图代表他们猜测如何有效地做到这一点

哪一个更好:接受
对象[]
IEnumerable
参数对象[]


我们究竟怎么知道?我们不是调用该方法的人。您应该询问的人是将编写代码来调用您的方法的人。

任何事情都有可能,但我们可能需要更多信息。你的问题是,你想得到某种类型T的任何序列吗?或者任何序列的任何东西(也就是说,任何类型的)。也就是说,您更关心的是T[]vs List vs HashSet,还是T[]vs List vs HashSet?这个问题没有统一的答案。这确实关系到你想要实现什么。你可以避免第一个,只实现第二个和第三个,因为对象[]可以传递给params对象[]……一维数组的类型是
IList
(及其基本接口)。@Inerdial这是真的,但是像
Add
这样的东西是不受支持的。我添加它主要是为了完整性——当您想要接受数组时,您可以同时使用这两种方法。(
IEnumerable
确实表明您不想更好地修改集合。)