24

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

  • public static string Join(string separator, params Object[] values)
  • public static string Join(string separator, IEnumerable<T> 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<T>函数来解决歧义:

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

但是我可以调用这个params object[]函数吗?

我正在使用 C# 4.0,如果这有什么不同的话。

4

5 回答 5

32

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

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

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

关于您对性能的评论,如果性能如此关键,请不要忘记对这两个选项进行基准测试。不要假设一个比另一个快。(并且始终分析您的整个应用程序——任何瓶颈都可能在其他地方。)

于 2013-04-10T18:33:13.263 回答
3

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

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

您还可以将其显式转换为object[]: string.Join("\n", (object[])arr);

于 2013-04-10T18:33:44.430 回答
0

对您的代码最简单的更改是:

    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# 重载解析

重载解决方案本身就是一个有趣的主题,但我还没有发现它是性能问题的瓶颈。

于 2013-04-10T18:45:01.467 回答
0

您可以像这样调用另一个重载(这就是param的用途) -

string text = string.Join("\n", new MyClass(), new MyClass());
于 2013-04-10T18:37:51.523 回答
0

如果您正在使用IEnumerable,您可以使用该方法的<object>通用重载ToArray()

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

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

于 2016-08-25T20:18:44.993 回答