Как получить свойство Static с отражением

Итак, это кажется довольно простым, но я не могу заставить его работать. У меня есть Object, и я использую рефлексию, чтобы получить к ней публичные свойства. Одно из этих свойств статично, и мне не повезло.

Public Function GetProp(ByRef obj As Object, ByVal propName as String) as PropertyInfo
    Return obj.GetType.GetProperty(propName)

End Function

Вышеприведенный код отлично подходит для свойств Public Instance, которые до сих пор - все, что мне нужно. Предположительно, я могу использовать BindingFlags для запроса других типов свойств (private, static), но я не могу найти правильную комбинацию.

Public Function GetProp(ByRef obj As Object, ByVal propName as String) as PropertyInfo
    Return obj.GetType.GetProperty(propName, Reflection.BindingFlags.Static Or Reflection.BindingFlags.Instance Or Reflection.BindingFlags.Public)

End Function

Но тем не менее, запрос каких-либо участников статики ничего не возвращает. Отражатель .NET может видеть, что статические свойства просто прекрасны, поэтому я явно что-то пропустил.

Ответ 1

Хорошо, поэтому ключ для меня состоял в использовании .FlattenHierarchy BindingFlag. Я действительно не знаю, почему я просто добавил его в уговоре и начал работать. Таким образом, окончательное решение, позволяющее мне получить Public Instance или Static Properties:

obj.GetType.GetProperty(propName, Reflection.BindingFlags.Public _
  Or Reflection.BindingFlags.Static Or Reflection.BindingFlags.Instance Or _
  Reflection.BindingFlags.FlattenHierarchy)

Ответ 2

Или просто посмотрите на это...

Type type = typeof(MyClass); // MyClass is static class with static properties
foreach (var p in type.GetProperties())
{
   var v = p.GetValue(null, null); // static classes cannot be instanced, so use null...
}

Ответ 3

Это С#, но должен дать вам идею:

public static void Main() {
    typeof(Program).GetProperty("GetMe", BindingFlags.NonPublic | BindingFlags.Static);
}

private static int GetMe {
    get { return 0; }
}

(вам нужно ИЛИ NonPublic и Static только)

Ответ 4

Немного ясности...

// Get a PropertyInfo of specific property type(T).GetProperty(....)
PropertyInfo propertyInfo;
propertyInfo = typeof(TypeWithTheStaticProperty)
    .GetProperty("NameOfStaticProperty", BindingFlags.Public | BindingFlags.Static); 

// Use the PropertyInfo to retrieve the value from the type by not passing in an instance
object value = propertyInfo.GetValue(null, null);

// Cast the value to the desired type
ExpectedType typedValue = (ExpectedType) value;

Ответ 5

myType.GetProperties(BindingFlags.Public | BindingFlags.Static |  BindingFlags.FlattenHierarchy);

Это вернет все статические свойства в статическом базовом классе или конкретном типе и, возможно, и в дочернем.

Ответ 6

Мне кажется, что работает ниже.

using System;
using System.Reflection;

public class ReflectStatic
{
    private static int SomeNumber {get; set;}
    public static object SomeReference {get; set;}
    static ReflectStatic()
    {
        SomeReference = new object();
        Console.WriteLine(SomeReference.GetHashCode());
    }
}

public class Program
{
    public static void Main()
    {
        var rs = new ReflectStatic();
        var pi = rs.GetType().GetProperty("SomeReference",  BindingFlags.Static | BindingFlags.Public);
        if(pi == null) { Console.WriteLine("Null!"); Environment.Exit(0);}
        Console.WriteLine(pi.GetValue(rs, null).GetHashCode());


    }
}

Ответ 7

Просто хотел прояснить это для себя, используя новый API отражения на основе TypeInfo - где BindingFlags недоступен надежно (в зависимости от целевой структуры).

В "новом" отражении, чтобы получить статические свойства для типа (не включая базовый класс (классы)), вы должны сделать что-то вроде:

IEnumerable<PropertyInfo> props = 
  type.GetTypeInfo().DeclaredProperties.Where(p => 
    (p.GetMethod != null && p.GetMethod.IsStatic) ||
    (p.SetMethod != null && p.SetMethod.IsStatic));

Обозначает свойства как для чтения, так и для записи (несмотря на то, что запись только для записи является ужасной идеей).

Элемент DeclaredProperties тоже не различает свойства с общедоступными/частными аксессорами - поэтому, чтобы фильтровать видимость, вам необходимо сделать это на основе используемого вами аксессуара. Например, если вы вернули вышеуказанный вызов, вы можете сделать:

var publicStaticReadable = props.Where(p => p.GetMethod != null && p.GetMethod.IsPublic);

Есть несколько доступных методов быстрого доступа, но в конечном итоге мы все будем писать намного больше методов расширения вокруг методов/свойств запроса TypeInfo в будущем. Кроме того, новый API заставляет нас думать о том, что мы теперь думаем как свойство 'private' или 'public', потому что мы должны фильтровать себя на основе отдельных аксессуаров.