params で IEnumerable を使用できないのはなぜですか? これは修正されますか?ジェネリックを使用するように古いライブラリを書き直してくれることを本当に望んでいます...
3 に答える
params で IEnumerable を使用できないのはなぜですか?
この質問は、設計チームが言語に機能を追加しない理由を提供する必要があることを前提としています。この前提は誤りです。
むしろ、機能を使用するためには、それを考え、設計し、指定し、実装し、テストし、文書化し、出荷する必要があります。これらはすべて大きなコストがかかります。
「params enumerable」機能は、考えられて設計されています。これは、指定、実装、テスト、文書化、または出荷されたことはありません。
したがって、この機能を使用することはできません。
更新: この記事の執筆時点で -- 2015 年初頭 -- が指定されましたが、2014 年の後半に C# 6.0 の実装、テスト、ドキュメント、および出荷が削減されました。 com/discussions/568820 .
まだ実装、テスト、文書化、および出荷されていないため、そのような機能はまだありません。うまくいけば、これは C# の仮想的な将来のバージョンになります。
更新: 「機能」が何を意味するのかを明確にする必要があります。なぜなら、「機能」とは何かという考えが頭の中にある可能性があるからです。私が話している機能は、次のようなことを言うことができるようにすることです
void Frob(params IEnumerable<int> x)
{
foreach(int y in x) ...
}
呼び出しサイトは、一連の整数を渡す「通常の形式」か、Frob(10, 20, 30) の「拡張形式」のいずれかになります。展開された形式の場合、コンパイラは、param 配列の場合と同じように、Frob(new int[] { 10, 20, 30}) と言ったかのように呼び出しを生成します。この機能のポイントは、メソッドが配列へのランダムアクセスを使用しないことが多いため、params が配列であるという要件を弱めることができるということです。代わりに、params は単にシーケンスである可能性があります。
オーバーロードを作成することで、今日これを行うことができます。
void Frob(params int[] x) { Frob((IEnumerable<int>)x); }
void Frob(IEnumerable<int> x)
{
foreach(int y in x) ...
}
これは少し痛いです。params 引数の型として IEnumerable を使用できるようにするだけで済みます。
これは修正されますか?
そうだといい。この機能は長い間リストに載っていました。これにより、多くの関数が LINQ でよりうまく機能するようになります。
Frob(from c in customers select c.Age);
Frob の 2 つの異なるバージョンを作成する必要はありません。
ただし、これは単なる「小さな便利」な機能です。実際には、言語にまったく新しい力を追加するわけではありません。そのため、優先順位リストで「仕様が書かれている」段階に達するのに十分なほど高くなることはありませんでした。
ジェネリックを使用するように古いライブラリを書き直してほしいと心から願っています。
コメントあり。
ああ、私は今あなたの言いたいことを理解したかもしれないと思います。次のようなメソッドを宣言できるようにしたいと思います。
public void Foo<T>(params IEnumerable<T> items)
{
}
そして、次のような「通常の」引数で呼び出すことができます。
IEnumerable<string> existingEnumerable = ...;
Foo(existingEnumerable);
または、次のような複数のパラメーターを使用します。
Foo("first", "second", "third");
それはあなたが求めているものですか?(単一の要素でT=string
はなく、最初のフォームで を使用することに注意してください...)T=IEnumerable<string>
もしそうなら、私はそれが役に立つかもしれないことに同意します-しかし、持っているのは簡単です:
public void Foo<T>(params T[] items)
{
Foo((IEnumerable<T>) items);
}
public void Foo<T>(IEnumerable<T> items)
{
}
上記を特に醜い回避策にするのに十分な頻度でこれを行うとは思いません。
上記のコードを呼び出すときは、コンパイラが例を優先するのを避けるために、型引数を明示的にparams
指定する必要があることに注意してください。たとえば、次のようになります。
List<string> x = new List<string>();
Foo<string>(x);
params パラメーターは配列として送信され、配列としてIEnumerable<T>
機能するために必要なランダム アクセスは提供されません。
メソッドを呼び出すときに、IEnumerable から配列を作成する必要があります。
TheMethod(theIEnumerable.ToArray());