将数组传递给params object 或IEnumerable 的函数

我想将一个自定义对象数组传递给像String.Join这样的函数,该函数具有以下签名:

  • public static string Join(string separator, params Object[] values)
  • public static string Join(string separator, IEnumerable values)

如果我这样调用函数:

 var arr = new MyClass[]{ new MyClass(), new MyClass() }; string text = string.Join("\n", arr); 

我收到编译器错误:

以下方法或属性之间的调用不明确:’string.Join(string,params object [])’和’string.Join(string,System.Collections.Generic.IEnumerable)’

我可以通过使用IEnumerable函数解决歧义:

 var arr = new MyClass[]{ new MyClass(), new MyClass() }; string text = string.Join("\n", arr); 

但我可以调用params object[]函数吗? 在性能关键的情况下,最好是直接访问数组而不是通过枚举器。

我正在使用C#4.0,如果这有任何区别。

如果传递一个object[]作为第二个参数,编译器应该选择object[]重载,因为它完全匹配。 在你有一个不同类型的数组(在这种情况下是MyClass[] )的情况下,只需将数组转换为object[]

 string.Join("\n", (object[])arr); 

实际上,您并未实际更改任何对象的类型或在运行时执行任何转换,您只需向编译器提供有关使用哪个重载的提示。

关于您对性能的评论,如果性能至关重要,请不要忘记对这两个选项进行基准测试。 不要以为一个比另一个快。 (并且总是描述您的整个应用程序 – 任何瓶颈都可能在其他地方。)

如果将arr变量的类型更改为object[] ,则会调用另一个重载:

 object[] arr = new MyClass[] { new MyClass(), new MyClass() }; string text = string.Join("\n", arr); 

你也可以显式地将它转换为object[] :string.Join(“\ n”,(object [])arr);

您可以像这样调用另一个重载(这是param用于) –

 string text = string.Join("\n", new MyClass(), new MyClass()); 

对代码的最简单更改是:

  var arr = new MyClass[]{ new MyClass(), new MyClass() }; string text = string.Join("\n", arr); 

至:

  var arr = new object[]{ new MyClass(), new MyClass() }; string text = string.Join("\n", arr); 

如前所述,铸造也有效:

  var arr = new MyClass[]{ new MyClass(), new MyClass() }; string text = string.Join("\n", (object[])arr); 

要了解有关此主题的更多信息,请研究C#重载决议 。

过载分辨率本身就是一个有趣的主题,但我还没有发现它是性能问题的瓶颈。

如果您正在使用IEnumerable ,则可以使用ToArray()方法的generics重载:

 var allFoos = foo.GetAllFoos().ToArray(); string s = string.Join(", ", allFoos); 

看起来不那么臃肿,对我来说更具可读性。