Как получить статическое свойство с помощью Reflection - PullRequest
98 голосов
/ 16 января 2009

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

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

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

Ответы [ 8 ]

116 голосов
/ 02 августа 2010

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

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...
}
41 голосов
/ 16 января 2009

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

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

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

(вам нужно ИЛИ только для непубличных и статических)

33 голосов
/ 18 июля 2012

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

// 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;
27 голосов
/ 19 января 2009

Хорошо, поэтому для меня ключевым было использование .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)
6 голосов
/ 28 июня 2011
myType.GetProperties(BindingFlags.Public | BindingFlags.Static |  BindingFlags.FlattenHierarchy);

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

2 голосов
/ 21 августа 2015

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

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

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 заставляет нас теперь думать о том, что мы считаем «частным» или «общедоступным» свойством, потому что мы должны фильтровать себя на основе отдельных методов доступа.

1 голос
/ 16 января 2009

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

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


    }
}
0 голосов
/ 16 января 2009

Попробуйте эту ссылку C # Reflection .

Примечание. Я думаю, что BindingFlags.Instance и BindingFlags.Static являются исключительными.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...