将数组传递给params object []或IEnumerable <t> </t>的函数

时间:2013-04-10 18:29:56

标签: c#

我想将一组自定义对象传递给像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,如果这有任何区别。

5 个答案:

答案 0 :(得分:25)

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

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

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

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

答案 1 :(得分:3)

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

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

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

答案 2 :(得分:0)

您可以像这样调用其他重载(这是param所用的) -

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

答案 3 :(得分: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# overload resolution

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

答案 4 :(得分:0)

如果您使用IEnumerable,则可以使用<object>方法的ToArray()泛型重载:

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

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