[解決済み] なぜC#はインデックス付きプロパティを実装しないのか?
質問
わかってる、わかってるんだけど...。この種の質問に対するEric Lippertの答えは、たいてい"のようなものです。 なぜなら、それは設計、実装、テスト、および文書化のコストに見合うものではなかったからです というものです。
それにしても、もっとちゃんとした説明が欲しい...。私が読んでいたのは C# 4 の新しい機能に関するこのブログの記事 を読んでいて、COM Interop についてのセクションで、次の部分が私の注意を引きました。
ところで、このコードではもう一つ新しい機能を使用しています。インデックス付きのプロパティです(Rangeの後の角かっこをよく見てください)。 しかし、この機能はCOMとの相互運用のためにのみ利用可能であり、C# 4.0では独自のインデックス付きプロパティを作成することはできません。 .
OK、でもなぜ?C#でインデックス付きプロパティを作成できないことは既に知っていて後悔していたのですが、この文章で改めて考えてみました。私はそれを実装するためのいくつかの良い理由を見ることができます。
-
CLR がそれをサポートしている (たとえば
PropertyInfo.GetValue
にはindex
パラメータがある)ので、C#ではそれを利用できないのが残念です。 - にあるように、COM の相互運用のためにサポートされています (動的ディスパッチを使用)。
- VB.NET で実装されています。
-
はすでにインデクサを作成することが可能であり、すなわち、オブジェクト自体にインデックスを適用することができます。
this
をプロパティ名で置き換えるだけです。
というようなことが書けるようになるのでは.
public class Foo
{
private string[] _values = new string[3];
public string Values[int index]
{
get { return _values[index]; }
set { _values[index] = value; }
}
}
現在のところ、私が知っている唯一の回避策は、インナークラス (
ValuesCollection
など) を作成し、インデクサを実装している
Values
プロパティを変更し、その内部クラスのインスタンスを返すようにします。
これはとても簡単なことですが、厄介なことです...。なので、おそらくコンパイラは私たちのためにそれを行うことができます!
// interface defined in the namespace System
public interface IIndexer<TIndex, TValue>
{
TValue this[TIndex index] { get; set; }
}
public class Foo
{
private string[] _values = new string[3];
private class <>c__DisplayClass1 : IIndexer<int, string>
{
private Foo _foo;
public <>c__DisplayClass1(Foo foo)
{
_foo = foo;
}
public string this[int index]
{
get { return _foo._values[index]; }
set { _foo._values[index] = value; }
}
}
private IIndexer<int, string> <>f__valuesIndexer;
public IIndexer<int, string> Values
{
get
{
if (<>f__valuesIndexer == null)
<>f__valuesIndexer = new <>c__DisplayClass1(this);
return <>f__valuesIndexer;
}
}
}
しかし、もちろん、その場合、プロパティは
実際に
を返します。
IIndexer<int, string>
を返すだけで、本当の意味でのインデックス付きプロパティにはならない...。本当のCLRインデックス付きプロパティを生成する方がよいでしょう。
あなたはどう思いますか?あなたはC#でこの機能を見たいと思いますか?もしそうでなければ、なぜですか?
どのように解決するのですか?
C#4をどのように設計したかを説明します。
まず私たちは、言語に追加することを考えられるすべての可能な機能のリストを作りました。
それから私たちは、機能を「これは悪いことだ、絶対にやってはいけない」「これはすごいことだ、やらなければならない」「これは良いことだ、でも今回はやめよう」というようにバケット分けしました。
それから私たちは、設計、実装、テスト、文書化、出荷、および「しなければならない」機能の保守にどれだけの予算があるか調べ、100%予算オーバーであることを発見しました。
そこで私たちは、多くのものを "gotta have" のバケツから "nice to have" のバケツに移動させました。
インデックス化されたプロパティはどこにもなかった に近いものではありませんでした。
に近いものではありませんでした。これらは、「良い」リストでは非常に低く、「悪い」リストに入りかけています。
素晴らしい機能 X の設計、実装、テスト、文書化、またはメンテナンスに費やす時間はすべて、素晴らしい機能 A、B、C、D、E、F、G に費やすことができない時間なのです。インデックス付きのプロパティは素晴らしいものですが、実際に実装されるには十分なほど良いものではありません。
関連
-
[解決済み】WebForms UnobtrusiveValidationModeは、jqueryのScriptResourceMappingを必要とする
-
[解決済み】「...は'型'であり、与えられたコンテキストでは有効ではありません」を解決するにはどうすればよいですか?(C#)
-
[解決済み] 関数を終了するには?
-
[解決済み】名前 'ViewBag' が現在のコンテキストに存在しない - Visual Studio 2015
-
[解決済み] なぜList<T>を継承しないのですか?
-
[解決済み] EqualsメソッドがオーバーライドされたときにGetHashCodeをオーバーライドすることが重要な理由は何ですか?
-
[解決済み] C#でHashtableよりDictionaryが好まれる理由とは?
-
[解決済み] なぜC#は静的メソッドにインターフェイスを実装できないのか?
-
[解決済み】C#には拡張プロパティがある?
-
[解決済み】C#でprivateプロパティを使用する理由はあるのでしょうか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] エンティティタイプ ApplicationUser は、現在のコンテキストのモデルの一部ではありません。
-
[解決済み】ソケットのアドレス(プロトコル/ネットワークアドレス/ポート)は、通常1つしか使用できない?
-
[解決済み】非静的メソッドはターゲットを必要とする
-
[解決済み】リソースの読み込みに失敗した:ステータス500(内部サーバーエラー)のサーバーの応答)
-
[解決済み】WPFでXamlファイルにコメントを追加する方法は?
-
[解決済み】取り消せないメンバはメソッドのように使えない?
-
[解決済み】ファイルへの読み書きの際に共有違反のIOExceptionが発生する C#
-
[解決済み] [Solved] .NETでスレッドの終了を待つには?
-
[解決済み】ユーザー設定値を別のユーザー設定値で設定する
-
[解決済み】データが存在しないのに読み込もうとする試みが無効である