1. ホーム
  2. c#

[解決済み] なぜC#はインデックス付きプロパティを実装しないのか?

2023-06-28 01:17:12

質問

わかってる、わかってるんだけど...。この種の質問に対する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 に費やすことができない時間なのです。インデックス付きのプロパティは素晴らしいものですが、実際に実装されるには十分なほど良いものではありません。