Yansıma ile Statik özellik nasıl elde edilir


109

Yani bu oldukça basit görünüyor ama işe yarayamıyorum. Bir Nesnem var ve kamuya açık özelliklerine ulaşmak için yansımayı kullanıyorum. Bu özelliklerden biri statik ve ona ulaşma konusunda hiç şansım yok.

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

End Function

Yukarıdaki kod, şimdiye kadar ihtiyacım olan tek şey olan Public Instance özellikleri için iyi çalışıyor. Sözde BindingFlags'i diğer özellik türlerini (özel, statik) istemek için kullanabilirim, ancak doğru kombinasyonu bulamıyorum.

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

Ancak yine de, herhangi bir Statik üye istemek hiçbir şey döndürmez. .NET reflektörü statik özellikleri gayet iyi görebiliyor, bu yüzden açıkça burada bir şeyi kaçırıyorum.


Bu gerçekten buna çok benziyor: stackoverflow.com/questions/392122/…
ctacke

Her ikisinin de BindingFlags kullanması benzer. Statik veya Örnek olsun, Herkese Açık üyeler edinmeme izin verecek belirli bir BindingFlags kombinasyonu arıyorum.
Corey Downie

Yanıtlar:


129

Ya da şuna bir bakın ...

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
Bu iki boş değer hangi değişkenlere karşılık gelir? Mümkünse bunu adlandırılmış argümanlar kullanarak nasıl yazarsınız? Teşekkürler.
Hamish Grubijan

Dahili statik sınıf için?
Kiquenet

Bu en iyi seçenek, bence cevap olarak seçilmelidir.
c0y0teX

8
p.GetValue(null);çok çalışıyor. İkincisi nullgerekli değildir.
Chrono

Harika görünüyor. Amaç, özelliği bir ad argümanına dayalı olarak elde etmekti - bunu başarmak için ever özelliği üzerinden döngü yapmak isteyeceğimi sanmıyorum.
Corey Downie

42

Bu C #, ancak size şu fikri vermeli:

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

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

(Yalnızca VEYA Kamuya Açık Olmayan ve Statik yapmanız gerekir)


3
Benim durumumda, yalnızca bu iki bayrağı kullanmak işe yaramadı. Ayrıca .FlattenHierarchy bayrağını kullanmak zorunda kaldım.
Corey Downie

3
@CoreyDownie kabul etti. BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchybenim için işe yarayan tek şeydi.
Jonathon Reinhart

40

Biraz netlik ...

// 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.Staticbenim için çözdü.
LosManos

28

Tamam, bu yüzden benim için anahtar .FlattenHierarchy BindingFlag. Bunu neden bir önseziyle eklediğimi gerçekten bilmiyorum ve çalışmaya başladı. Dolayısıyla, Genel Örnek veya Statik Özellikler almamı sağlayan son çözüm şudur:

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

Bu, statik temel sınıf veya belirli bir türdeki tüm statik özellikleri ve muhtemelen alt sınıfı da döndürecektir.


2

Güvenilir bir şekilde mevcut olmayan TypeInfoyerlerde BindingFlags(hedef çerçeveye bağlı olarak) dayalı yeni yansıma API'sini kullanırken bunu kendim için netleştirmek istedim .

'Yeni' yansımada, bir türün statik özelliklerini elde etmek için (temel sınıf (lar) dahil değil) aşağıdaki gibi bir şey yapmanız gerekir:

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

Hem salt okunur hem de salt okunur özelliklere sahiptir (yalnızca yazma, berbat bir fikir olmasına rağmen).

DeclaredPropertiesÜyesi de kamu / özel erişimcilerle özellikleri arasında ayrım yapmaz - yani bir görüş açısı filtreye, o zaman kullanmak gerekir erişgeç dayalı bunu yapmak gerekir. Örneğin - yukarıdaki çağrının geri döndüğünü varsayarsak, şunları yapabilirsiniz:

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

Kullanılabilir bazı kısayol yöntemleri var - ancak nihayetinde hepimiz TypeInfogelecekte sorgu yöntemleri / özellikleri etrafında çok daha fazla uzantı yöntemi yazacağız . Ayrıca, yeni API bizi bundan sonra tam olarak 'özel' veya 'genel' mülkiyet olarak düşündüğümüz şeyi düşünmeye zorluyor - çünkü kendimizi bireysel erişimcilere göre filtrelemeliyiz.


1

Aşağıdakiler benim için çalışıyor gibi görünüyor.

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


    }
}

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.