Як отримати статичну властивість за допомогою відображення


109

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

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

Ну це схоже тим, що вони обидва використовують BindingFlags. Я шукаю специфічну комбінацію BindingFlags, яка дозволить мені отримати публічних членів, будь то статичні чи екземпляри.
Corey Downie

Відповіді:


129

Або просто подивіться на це ...

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

2
Яким змінним відповідають ці два нулі? Як би ви написали це, використовуючи названі аргументи, якщо це можливо? Дякую.
Гаміш Грубіян

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

Це найкращий варіант, на мою думку, його слід обрати як відповідь.
c0y0teX

8
p.GetValue(null);працює теж. Друге nullне потрібно.
Хроно

Виглядає здорово. Мета полягала в тому, щоб отримати властивість на основі аргументу імені - я не думаю, що я хотів би перетворити цикл на будь-яку власність, щоб досягти цього.
Corey Downie

42

Це C #, але має дати вам ідею:

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

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

(потрібно АБО непрофільне та статичне)


3
У моєму випадку використовувати лише ці два прапори не вийшло. Мені довелося також використовувати прапор .FlattenHierarchy.
Corey Downie

3
@CoreyDownie погодився. BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchyбуло єдине, що працювало на мене.
Джонатан Райнхарт

40

Трохи ясності ...

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

1
BindingFlags.Instance | BindingFlags.Staticвирішив це для мене.
ЛосМанос

28

Гаразд, ключовим для мене було використання FlattenHierarchy BindingFlag. Я насправді не знаю, чому я просто додав його на переконання, і він почав працювати. Таким чином, остаточне рішення, яке дозволяє мені отримати публічний екземпляр або статичні властивості, це:

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

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

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


2

Просто хотів уточнити це для себе, використовуючи при цьому новий 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 змушує нас думати саме про те, що ми вважаємо "приватною" чи "публічною" власністю відтепер - тому що ми мусимо фільтрувати себе на основі окремих постачальників.


1

Нижче, здається, працює для мене.

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


    }
}

-3

Спробуйте це посилання C # Reflection .

Примітка. Я думаю, що BindingFlags.Instance і BindingFlags.Static є ексклюзивними.


Так, я сподіваюся, що це не так, тому що я хочу, щоб я міг отримати будь-який державний екземпляр чи статичну.
Corey Downie

Вони не є ексклюзивними. Я просто тестував це.
LosManos
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.