Как получить статическое свойство с помощью Reflection

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

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

End Function

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

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 прекрасно видит статические свойства, так что мне явно чего-то не хватает.

Это действительно очень похоже на это: stackoverflow.com/questions/392122/…

ctacke 16.01.2009 21:42

Это похоже на то, что они оба используют BindingFlags. Я ищу конкретную комбинацию BindingFlags, которая позволит мне получить публичные члены, будь то статические или экземпляры.

Corey Downie 16.01.2009 22:19
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
117
2
112 157
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

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

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

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

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

В моем случае использование только этих двух флагов не сработало. Мне также пришлось использовать флаг .FlattenHierarchy.

Corey Downie 16.08.2011 20:47

@CoreyDownie согласился. BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy был единственным, что у меня сработало.

Jonathon Reinhart 02.05.2012 19:47

Попробуйте эту ссылку C# Отражение.

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

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

Corey Downie 16.01.2009 22:20

Они не исключительны. Я только что это проверил.

LosManos 19.02.2018 23:44

Кажется, что ниже работает для меня.

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


    }
}
Ответ принят как подходящий

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

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

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

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...
}

Каким переменным соответствуют эти два нуля? Как бы вы написали это, используя именованные аргументы, если это возможно? Спасибо.

Hamish Grubijan 20.03.2012 02:55

Для внутреннего статического класса?

Kiquenet 23.02.2016 14:55

Это лучший вариант, на мой взгляд, его следует выбрать в качестве ответа.

c0y0teX 10.04.2017 21:58
p.GetValue(null); тоже работает. Второй null не требуется.
Chrono 18.07.2017 16:55

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

Corey Downie 05.03.2020 04:39

@Chrono, раньше было, поэтому в посте это было.

Bojidar Stanchev 28.05.2020 14:54
myType.GetProperties(BindingFlags.Public | BindingFlags.Static |  BindingFlags.FlattenHierarchy);

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

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

// 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;
BindingFlags.Instance | BindingFlags.Static решил это за меня.
LosManos 19.02.2018 23:45

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

Другие вопросы по теме