LoginSignup
7
7

More than 5 years have passed since last update.

インデックサ this[] をリフレクションで取得する

Last updated at Posted at 2014-09-11

以下のように定義されているインデクサをリフレクションで取得してみましょう。

public object this[int index]
{
    get {  }
    set {  }
}

通常のプロパティであれば、以下のようにして取得できます。
( Hoge クラスの Fuga プロパティの場合)

var pi = typeof(Hoge).GetProperty("Fuga", BindingFlags.Public | BindingFlags.Instance)

しかし、インデクサはプロパティ名がないので、上記のように書けません。
と思われますが、このように書くと取得できます。

var pi = typeof(Hoge).GetProperty("Item", BindingFlags.Public | BindingFlags.Instance)

インデクサは内部的に Item と名前で扱われてるんですね。 ※追記あり
試しにこういう定義をしてみましょう。

public class Hoge
{
    public object Item { get; set; }
    public object this[int indexer] { get; set; }
}

すると'Hoge' は 'Item' の定義を既に含んでいます。というエラーが発生します。
このことからもインデクサが Item として扱われてることがわかりますね。

追記

@tomochan154 さん、 @chocolamint さんからコメントを頂きました。
まずインデクサを複数定義した場合、上のリフレクションでは例外が発生します。。
また、 IndexerNameAttribute でインデクサの名前を Item 以外に変更する事もできるので、GetProperty("Item", ... と書く方法も適切でないことが分かりました。

お二人から紹介された方法を下に書いておきます。

// this[int index] 一本釣り
var types = new[] { typeof(Int32) };
var pi = typeof(Hoge).GetProperties(BindingFlags.Public | BindingFlags.Instance)
    .First(pp => pp.GetIndexParameters().Select(pr => pr.ParameterType).SequenceEqual(types));
// インデクサ全部
var pis = typeof(Hoge).GetProperties(BindingFlags.Public | BindingFlags.Instance)
    .Where(p => p.GetIndexParameters().Length > 0).ToArray();
// this[int index] 一本釣り
var types = new[] { typeof(Int32) };
var type = typeof(Hoge);
var pi = type.GetProperty(type.GetCustomAttribute<DefaultMemberAttribute>().MemberName, types);
7
7
7

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7