it-swarm.com.de

So erhalten Sie eine statische Eigenschaft mit Reflection

Das scheint also ziemlich einfach zu sein, aber ich kann es nicht zum Laufen bringen. Ich habe ein Objekt und benutze Reflexion, um zu seinen öffentlichen Eigenschaften zu gelangen. Eine dieser Eigenschaften ist statisch und ich habe kein Glück, sie zu erreichen.

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

End Function

Der obige Code funktioniert gut für Public Instance-Eigenschaften, was bis jetzt alles ist, was ich gebraucht habe. Angeblich kann ich BindingFlags verwenden, um andere Arten von Eigenschaften anzufordern (privat, statisch), aber ich kann anscheinend nicht die richtige Kombination finden.

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

Wenn Sie jedoch statische Mitglieder anfordern, wird nichts zurückgegeben. .NET Reflector kann die statischen Eigenschaften gut erkennen, daher fehlt mir hier eindeutig etwas.

100
Corey Downie

Ok, also war der Schlüssel für mich, das .FlattenHierarchy BindingFlag zu verwenden. Ich weiß nicht genau, warum ich es soeben hinzugefügt habe und es hat angefangen zu funktionieren. Die endgültige Lösung, mit der ich öffentliche Instanzen oder statische Eigenschaften erhalten kann, ist:

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

Oder schauen Sie sich das an ...

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

Dies ist C #, sollte Ihnen aber die Idee geben:

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

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

(Sie müssen OR NonPublic und Static only)

41
earlNameless

Ein bisschen Klarheit ...

// 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;
33
George
myType.GetProperties(BindingFlags.Public | BindingFlags.Static |  BindingFlags.FlattenHierarchy);

Dadurch werden alle statischen Eigenschaften in der statischen Basisklasse oder einem bestimmten Typ und wahrscheinlich auch das untergeordnete Element zurückgegeben.

6
Igor

Ich wollte dies nur für mich klären, während ich die neue Reflection-API auf Basis von TypeInfo verwende - wobei BindingFlags nicht zuverlässig verfügbar ist (abhängig vom Ziel-Framework).

Um die statischen Eigenschaften für einen Typ (ohne Basisklasse (n)) zu erhalten, müssen Sie in der 'neuen' Überlegung Folgendes tun:

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

Berücksichtigt sowohl schreibgeschützte als auch schreibgeschützte Eigenschaften (obwohl schreibgeschützte Eigenschaften eine schreckliche Idee sind).

Auch das DeclaredProperties -Mitglied unterscheidet nicht zwischen Eigenschaften mit öffentlichen/privaten Zugriffsmechanismen. Wenn Sie also nach der Sichtbarkeit filtern möchten, müssen Sie dies basierend auf dem Zugriffsmechanismus tun, den Sie verwenden möchten. Zum Beispiel: Angenommen, der obige Anruf ist zurückgekehrt, können Sie Folgendes tun:

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

Es gibt einige Verknüpfungsmethoden, aber letztendlich werden wir alle in Zukunft viel mehr Erweiterungsmethoden für die Abfragemethoden/-eigenschaften von TypeInfo schreiben. Die neue API zwingt uns außerdem dazu, genau darüber nachzudenken, was wir von nun an als "private" oder "öffentliche" Eigenschaft betrachten - weil wir uns nach einzelnen Zugriffsmethoden filtern müssen.

2
Andras Zoltan

Das Folgende scheint für mich zu funktionieren.

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


    }
}
1
Vyas Bharghava