web-dev-qa-db-ja.com

params object []またはIEnumerable <T>のいずれかを取る関数に配列を渡します

カスタムオブジェクトの配列を、次のシグネチャを持つ_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を使用しています。

21
bouvierr

2番目のパラメーターとしてobject[]を渡す場合、コンパイラーはobject[]オーバーロードを選択する必要があります。これは、完全に一致するためです。異なる型の配列(この場合はMyClass[])がある場合は、配列をobject[]にキャストするだけです。

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

実際にオブジェクトのタイプを変更したり、実行時に変換を実行したりするのではなく、使用するオーバーロードに関するヒントをコンパイラーに提供するだけです。

また、パフォーマンスに関するコメントについては、パフォーマンスが非常に重要な場合は、両方のオプションのベンチマークを忘れないでください。一方が他方より速いと思い込まないでください。 (そして、常にアプリケーション全体のプロファイルを作成してください。ボトルネックは他の場所にある可能性があります。)

28
cdhowie

arr変数のタイプをobject[]に変更すると、他のオーバーロードが呼び出されます。

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

明示的にobject[]にキャストすることもできます:string.Join( "\ n"、(object [])arr);

3
Wouter de Kort

このように他のオーバーロードを呼び出すことができます(これが param の用途です)-

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

IEnumerableを使用している場合は、ToArray()メソッドの<object>汎用オーバーロードを使用できます。

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

膨満感が少なく、読みやすく見えます。

0
Kemuel Sanchez

コードへの最も簡単な変更は、次のようにすることです。

    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#オーバーロード解決 を調べてください。

過負荷の解決はそれ自体が興味深いテーマですが、パフォーマンスの問題のボトルネックになるとはまだ思っていません。

0
Doug