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

发布于 2024-12-25 22:15:59 字数 667 浏览 0 评论 0 原文

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

那么...

是否可以编写一个函数来接受单一类型对象的各种级别的列表类型? 作为一个附带问题,在设计类的接口时,最好接受 object[]IEnumerableparams object[ ]? (编辑:从问题中删除,因为已经发生了足够多的事情。)

例如,我正在考虑一个接受两个/全部 object[], IEumerable,并可能进一步嵌套:IEnumerable>object[][](以及,等等)。

这可能吗?

Some context: I'd like to write a class where the main method for adding things to a collection is through a method (or methods) that are named Add (or something like that). And so the signature that seems best is params object[]. Internally, this very function would have to switch/if-else all the types that it can accept. So, initially it could accept this object[] array, but I might like to see it also accept object[][], and object[][][], etc, and then the method/function could flatten internally, so the user wouldn't need to do that prior to calling this function.

So...

Is it possible to write a function that can accept various Levels of List types for a single kind of object? As a side question, when designing an interface to a class, which is better to accept object[] or IEnumerable<object> or params object[]? (Edit: struck from the question because there is already enough going on.)

For instance, I'm thinking of a function that accepts both/all of object[], IEumerable<object>, and possibly further nesting like: IEnumerable<IEnumerable<object>>, object[][] (and on, on and on, etc).

Is this possible?

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

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

发布评论

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

评论(4

遗心遗梦遗幸福 2025-01-01 22:15:59

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

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

哪个更好:接受 object[]IEnumerableparams object[]

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

You'll notice that the List<T> class itself has methods Add that takes a T and AddRange that takes a sequence of T. We do not attempt to overload Add to do both, for two reasons. First, because adding a thing and adding a bunch of things are logically different, and second, because it greatly complicates overload resolution.

If you want a method that takes a sequence of T, then write a method that takes a sequence of T. If the caller has a sequence of sequences, make them flatten it; don't try to guess on their behalf how to do so effectively.

which is better: to accept object[] or IEnumerable<object> or params object[]?

How on earth should we know? We're not the ones calling the method. The person you should be asking is the person who is going to be writing code to call your method.

长途伴 2025-01-01 22:15:59

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

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

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

//etc etc

One option is just to make one function and then overload it however many times you need. You can make the overloaded functions call the "base" function.

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

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

//etc etc
来日方长 2025-01-01 22:15:59

这实际上取决于您所说的列表类型的含义。如果你的意思是明确的,那么你可以有一个接受 IList。如果您想将数组放入其中,那么您确实应该接受 IEnumerable。除非您需要修改它,否则数组将无法真正工作,因此您可以接受ICollection

It depends really on what you mean by list types. If you mean it explicitly, then you could have a method that accepts IList<T>. If you'd like to throw arrays into the mix, then you should really be accepting IEnumerable<T>. Unless you need to modify it, in which case arrays won't really work, so you could accept ICollection<T>.

不忘初心 2025-01-01 22:15:59

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

Make two overloads of one function, one that accepts IEnumerable<T>, and one that accepts params T[]. Implement the latter by calling the former. Forget the nesting, LINQ can flatten collections easily using SelectMany.

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