简体   繁体   English

在 C# 中使用反射识别自定义索引器

[英]Identifying a custom indexer using reflection in C#

I have a class with a custom indexer like so我有一个像这样的自定义索引器的类

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

How can I identify the custom indexer in the results of typeof(MyClass).GetProperties()?如何在 typeof(MyClass).GetProperties() 的结果中识别自定义索引器?

You can also look for index parameters, using the the PropertyInfo.GetIndexParameters method, if it returns more than 0 items, it's an indexed property:您还可以使用PropertyInfo.GetIndexParameters方法查找索引参数,如果它返回 0 个以上的项目,则它是一个索引属性:

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

Look for the DefaultMemberAttribute defined at type level.查找在类型级别定义的DefaultMemberAttribute

(This used to be IndexerNameAttribute , but they seem to have dropped it) (这曾经是IndexerNameAttribute ,但他们似乎已经放弃了它)

    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();
    }

If there is only one indexer, you can use this:如果只有一个索引器,你可以使用这个:

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

If there are multiple indexers, you can select the overload you want by supplying the arguments like this:如果有多个索引器,您可以通过提供如下参数来选择所需的重载:

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

You can create a helper extension like this:你可以像这样创建一个辅助扩展:

//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));
}

To get a known indexer you can use:要获得已知的索引器,您可以使用:

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

or you can get the getter method of the indexer:或者您可以获取索引器的 getter 方法:

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

if the class has only one indexer, you can omit the type:如果类只有一个索引器,则可以省略类型:

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

I've added this answer for the ones who google search led them here.我已经为谷歌搜索将他们带到这里的人添加了这个答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM