简体   繁体   中英

Getting all public static methods returns an empty list

I am trying to retrieve all public static fields in a class using reflection. For some reason the List is empty although it shouldn't. I am new to C# and came from java, so I probably misunderstood something. I hope someone can clarify this.

In my ReflectionUtils class:

    public static List<T> GetFieldValues<T>()
    {
        return typeof(T).GetFields(BindingFlags.Public | BindingFlags.Static)
                  .Where(f => f.FieldType is T)
                  .Select(f => (T) f.GetValue(null))
                  .ToList();
    }

In my MaterialType class:


public sealed class MaterialType
{

    public static readonly MaterialType GRASS = new MaterialType(1f);
    public static readonly MaterialType STONE = new MaterialType(1f);
    public static readonly MaterialType WATER = new MaterialType(1f);

    /* Just a constructor and a public readonly variable here */

    public static List<MaterialType> Values() {
        return ReflectionUtils.GetFieldValues<MaterialType>();
    }
}

Your problem is the is operator:

f.FieldType is T

This is not what you intended, because FieldType is an instance of a Type (-derived) class representing the type of the field. It's not itself assignable to a variable of type T .

So you should use:

f.FieldType == typeof(T)

f.FieldType is T is true if the FieldType property of f returns a value of type T .

But f is System.Reflection.FieldInfo , and it hasn't ever heard of your MaterialType class. f.FieldType actually returns an object of type System.Type (they heard you like types). For the fields you care about, that Type object it returns is going to be equal to typeof(MaterialType) . If T is MaterialType , typeof(T) will be typeof(MaterialType) as well.

public static List<T> GetFieldValues<T>()
{
    return typeof(T).GetFields(BindingFlags.Public | BindingFlags.Static)
              .Where(f => f.FieldType == typeof(T))
              .Select(f => (T)f.GetValue(null))
              .ToList();
}

To use is , you'd want to get the value from the field you're looking at, and then check if the type of the value is T . But there's already an OfType() LINQ method for that, so we'll use it. As noted elsewhere, this may involve getting values we don't need, so the above solution is preferable.

public static List<T> GetStaticFieldValuesOfType<T>()
{
    return typeof(T).GetFields(BindingFlags.Public | BindingFlags.Static)
              .Select(f => f.GetValue(null))
              .OfType<T>()
              .ToList();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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