Подтвердить что ты не робот

Указание пользовательского индексатора с использованием отражения в С#

У меня есть класс с настраиваемым индексом вроде

public string this[VehicleProperty property]
{
  // Code
}

Как я могу определить пользовательский индексатор в результатах typeof (MyClass).GetProperties()?

4b9b3361

Ответ 1

Вы также можете искать индексные параметры, используя метод PropertyInfo.GetIndexParameters, если он возвращает более 0 элементов, это индексированное свойство:

foreach (PropertyInfo pi in typeof(MyClass).GetProperties())
{
    if (pi.GetIndexParameters().Length > 0)
    {
       // Indexed property...
    }
}

Ответ 2

Ищите DefaultMemberAttribute, определенные на уровне уровня.

(Это было IndexerNameAttribute, но они, похоже, его сбросили)

Ответ 3

    static void Main(string[] args) {

        foreach (System.Reflection.PropertyInfo propertyInfo in typeof(System.Collections.ArrayList).GetProperties()) {

            System.Reflection.ParameterInfo[] parameterInfos = propertyInfo.GetIndexParameters();
            // then is indexer property
            if (parameterInfos.Length > 0) {
                System.Console.WriteLine(propertyInfo.Name);
            }
        }


        System.Console.ReadKey();
    }

Ответ 4

Чтобы получить известный индексатор, вы можете использовать:

var prop = typeof(MyClass).GetProperty("Item", new object[]{typeof(VehicleProperty)});
var value = prop.GetValue(classInstance, new object[]{ theVehicle });

или вы можете получить метод получения индексатора:

var getterMethod = typeof(MyClass).GetMethod("get_Item", new object[]{typeof(VehicleProperty)});
var value = getterMethod.Invoke(classInstance, new object[]{ theVehicle });

если класс имеет только один индексатор, вы можете опустить тип:

var prop = typeof(MyClass).GetProperty("Item", , BindingFlags.Public | BindingFlags.Instance);

Я добавил этот ответ для тех, кто привел их в поиск Google.

Ответ 5

Если есть только один индексатор, вы можете использовать это:

var indexer = typeof(MyClass).GetProperties().First(x => x.GetIndexParameters().Length > 0));

Если имеется несколько индексаторов, вы можете выбрать нужную перегрузку, указав следующие аргументы:

var args = new[] { typeof(int) };
var indexer = typeof(MyClass).GetProperties().First(x => x.GetIndexParameters().Select(y => y.ParameterType).SequenceEqual(args));

Вы можете создать вспомогательное расширение следующим образом:

//Usage      
var indexer = typeof(MyClass).GetIndexer(typeof(VehicleProperty));
//Class
public static class TypeExtensions
{
  public static PropertyInfo GetIndexer(this Type type, params Type[] arguments) => type.GetProperties().First(x => x.GetIndexParameters().Select(y => y.ParameterType).SequenceEqual(arguments));
}