この記事は機械翻訳のミラー記事です。元の記事にジャンプするにはこちらをクリックしてください。

眺める: 19672|答える: 1

[出典] . .NET 読み取り専用のコレクションインターフェースの物語

[リンクをコピー]
掲載地 2018/02/05 14:28:10 | | |
.NET 4.5新しいコレクションインターフェース、IReadOnlyListとIReadOnlyDictionaryが追加されました。 これらのインターフェースは表面的には平凡に見えるかもしれませんが、後方互換性、相互運用性、そして共可変性の役割について非常に複雑な物語を明らかにしています。

IReadOnlyListとIReadOnlyDictionaryは、.NET開発者が常に欲しがっていた2つのインターフェースです。 書き込み可能なインターフェースとは対照的に対称性を提供するだけでなく、読み取り専用インターフェースはNotSupportedException例外だけを投げて何もしないメソッドの実装を排除すべきです。 これらは時間の制約により完成しませんでした。

次のチャンスが来た。 NET 2.0。 これにより、Microsoftは弱い型のコレクションを廃止し、強型のピアコレクションに置き換えることができます。 しかし、基地ライブラリ[1]チームは再び読み取り専用リストを提供する機会を逃しました。Kit Georgeは次のように記しています。

Joeで話している問題に対してインターフェースを提供するのではなく、デフォルトの実装を提供するつもりなので、ReadOnlyCollectionBaseのベースクラスを提供しています。 しかし、強いタイプではないから使いたがらない人もいるのも理解できます。 しかしジェネリックの導入により、ReadOnlyCollectionも登場<T>しました。これにより、同じ機能だけでなく強力なタイプも提供できます。素晴らしいです!

ReadOnlyCollection<T>は密閉クラスではないため、必要に応じて自分のコレクションをフルスピードで書くことも可能です。 このために作成したこれらのコレクションは一般的なニーズに適応できるため、同じコンセプトのインターフェースを導入する予定はありません。

クシシュトフ・ツワリナもこのテーマについて自身の意見を述べました。

驚くかもしれませんが、読み取り<T>専用コレクションに使用する予定の2つのインターフェースはIListとIListです。 どちらもIsReadOnlyというブール属性を持ち、読み取り専用コレクションがこのプロパティを実装するとtrueが返るはずです。 純粋な読み取り専用インターフェースを追加したくない理由は、基本ライブラリに不必要な複雑さを加えすぎると感じているからです。 複雑さの観点からは、この新しいインターフェースとその消費者の両方を指します。

APIデザイナーが実行時にIsReadOnlyプロパティや例外を確認しないなら、この場合はIListインターフェースを使っても問題ないと考えています。 もし一度に本当にクリーンなカスタムAPIを提供してくれるなら、今回はIListインターフェースの実装を見せて、カスタマイズされた読み取り専用APIを公開すべきです。 後者はオブジェクトモデルから公開されたコレクションに典型的な方法です。

開発者たちはこの状況について不満を述べていますが、ジェネリックによる新たな機会の方がこの問題をはるかに上回っており、問題は... NET 4は以前はほとんど無視されていました。 しかし、この決定は一部の反応も引き起こしました。その点については後ほど説明します。

インで。 .NET 4のランタイムに新機能が追加されました。 以前のバージョンで。 .NETでは、インターフェースが型になると、そのインターフェースは過度に制限されています。 例えば、Customer が Person から継承したとしても、IEnumerable 型のオブジェクトを<Customer>型 IEnumerable の関数にパラメータとして渡すことは不可能です<Person>。 共変サポートの追加により、この制限は部分的に解除されました。

「部分的に」と言うのは、場合によってはIEmumableインターフェースではなく、リッチAPIを持つインターフェースを同時に使うべきだからです。 たとえIListインターフェースが共変でなくても、読み取り専用のリストインターフェースは共変であるべきです。 残念なことに。 .NETベースのライブラリチームは再びこの見落としに対処しないことを決定しました。

その後、WinRTの導入とCOMの復活がすべてを変えました。 COMの相互運用性はかつて開発者が他に選択肢がないときに使う技術でしたが、今では .NETプログラミングの礎です。 そしてWinRTはIVectorView<T>とIMapView<K、V>インターフェースを公開しているため、 .NETもそれに応じて調整する必要があります。

WinRTプログラムの興味深い特徴の一つは、各開発プラットフォームごとに異なるが類似したAPIが発表されていることです。 ご存知かもしれませんが、すべてのメソッド名はキャメルケーズド[2]で表され、C++や.NET開発者はメソッド名をPascalCased[3]と認識しています。 もう一つの大きな変更は、C++と.NETインターフェース間の自動マッピングです。 そこで。 .NET開発者はWindows.Foundation.Collections名前空間を扱う必要はなく、System.Collections.Genericの名前空間を使い続ければいいのです。 IVectorView<T>およびIMapView<K、V>インターフェースは、ランタイムでそれぞれIReadOnlyList<T>インターフェースおよびIReadOnlyDictionary<TKey、TValue>インターフェースに変換されます。

C++/WinRTのこれらのインターフェース名の方がある程度正確であることは注目に値します。 これらのインターフェースはコレクションの一部ビューを表現するために使われますが、インターフェース自体が不変であることを保証するものではありません。 経験豊富な人の中でも。 .NET開発者の間でよくある誤りは、ReadOnlyCollection型が不変コレクションのコピーであると誤解することですが、実際にはアクティブなコレクションのラッパーに過ぎません(読み取り専用、凍結、不変コレクションの詳細については、Andrew Arnottの同名投稿を参照してください)。

IList<T>インターフェースはIReadOnlyListインターフェースと同じメンバーを持ち<T>、すべてのIList型<T>リストは読み取り専用リストとして表現可能ですが、IList<T>はIReadOnlyListから継承していない<T>ため、この点を学ぶのは興味深いかもしれません。 イモ・ランドワースはこう説明しました。

この方法が機能する理由は、これらの読み取り専用インターフェースが純粋に読み書きインターフェースのサブセットであるためで、それは妥当な仮定のように思えます。 残念ながら、この前提は現実とは一致しません。なぜなら、各インターフェースのメタデータレベルでの各メソッドには独自のスロットがあるからです(これにより明示的なインターフェース実装が機能します)。

言い換えれば、読み取り専用インターフェースを変数クラスの基底クラスとして導入する唯一の方法は、にフォールバックすることです。 NET 2.0、つまり最初に考案された時期です。 完全に展開された後、唯一変更できるのは共変マーカーやインバータマーカー(VBやC#では「イン」と「アウト」として表される)を追加するだけです。

なぜIReadOnlyCollectionインターフェースがないのかと尋ね<T>られた際、Immoは次のように答えました。

この設計も検討しましたが、Count属性のみを提供する型を追加するだけでは基本ライブラリに大きな価値は加えられないと感じました。 ベースライブラリチームでは、APIがマイナス1000から始まる場合、価値を提供するだけでは追加を正当化するには不十分だと考えています。 新しいAPIを追加する理由にはコストも含まれます。例えば、開発者は選択肢が増えるためです。 最初は、この型を追加すれば、単にカウントを取って面白いことをしたい場合にコードのパフォーマンスが良くなると思っていました。 例えば、既存のコレクションに一括で追加する場合などです。 しかし、これらのシナリオでは、私たちはIEnumerableインターフェースのみ、<T>そして<T>ICollectionインターフェースを実装するインスタンスを持つ特別な場合に限り、利用することを推奨しています。 すべての組み込みコレクションタイプがこのインターフェースを実装して以来、これらの最も一般的なシナリオでパフォーマンス向上は見られていません。 ちなみに、<T>IEnumerableの拡張メソッドCount()もこれが可能です。

これらの新しいインターフェースは に対して利用可能です。 NET 4.5 と 。 NET for Windows 8。

翻訳注記

[1] ベースクラスライブラリ、略称BCL。 基本クラスライブラリの詳細については、MSDNへの参加をお願いします。

[2] キャメルケース、コム(こぶ)命名法、別名ロウ・キャメルケース。 形式は、最初の単語が小文字で始まるというものです。 2番目の単語の最初の文字は大文字で表記されます。例えば、firstName、lastNameなどです。

[3] パスカル・ケーゼド、パスカル命名法、別名上部ラクダケース。 形式は各単語の最初の文字を大文字で表記するもので、例えば FirstName、LastName、CamelCase などです。




先の:.NET/C#ソフトウェアライセンスプラットフォーム【ソースコード】
次に:JSマイニング - モネロはウェブマイニングでどのようにマイニングされるのか?
免責事項:
Code Farmer Networkが発行するすべてのソフトウェア、プログラミング資料、記事は学習および研究目的のみを目的としています。 上記の内容は商業的または違法な目的で使用されてはならず、そうでなければ利用者はすべての結果を負うことになります。 このサイトの情報はインターネットからのものであり、著作権紛争はこのサイトとは関係ありません。 ダウンロード後24時間以内に上記の内容を完全にパソコンから削除してください。 もしこのプログラムを気に入ったら、正規のソフトウェアを支持し、登録を購入し、より良い本物のサービスを受けてください。 もし侵害があれば、メールでご連絡ください。

Mail To:help@itsvse.com