リフレクションで静的プロパティを取得する方法


109

したがって、これはかなり基本的なように見えますが、機能させることができません。オブジェクトがあり、リフレクションを使用してそのパブリックプロパティにアクセスしています。これらのプロパティの1つは静的であり、私はそれに到達することができません。

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

End Function

上記のコードは、パブリックインスタンスのプロパティで問題なく機能します。おそらく、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を使用するという点で似ています。StaticまたはInstanceのパブリックメンバーを取得できるBindingFlagsの特定の組み合わせを探しています。
コーリー・ダウニー

回答:


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
これらの2つのnullはどの変数に対応しますか?可能であれば、名前付き引数を使用してこれをどのように記述しますか?ありがとう。
Hamish Grubijan 2012年

内部静的クラスの場合?
Kiquenet 2016

これは最良のオプションです。私の意見では、それは答えとして選択されるべきです。
c0y0teX 2017

8
p.GetValue(null);も動作します。2番目nullは必要ありません。
クロノ

素晴らしく見える。目標は、名前の引数に基づいてプロパティを取得することでした。これを実現するために、これまでのプロパティをループ処理する必要はないと思います。
コーリーダウニー

42

これはC#ですが、次のようになります。

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

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

(OR非公開および静的のみが必要です)


3
私の場合、これら2つのフラグのみを使用しても機能しませんでした。.FlattenHierarchyフラグも使用する必要がありました。
コーリーダウニー、

3
@CoreyDownieは同意しました。BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy私のために働いた唯一のものでした。
Jonathon Reinhart、2012年

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私のためにそれを解決しました。
LosManos

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

TypeInfo-に基づいて新しいリフレクションAPIを使用しながら、これを自分で明確にしたかっただけ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#リフレクションリンクを試してください。

BindingFlags.InstanceとBindingFlags.Staticは排他的である思います。


ええ、私はそうではないことを望んでいます。なぜなら、私がパブリックインスタンスまたはスタティックを取得できるようにしたいからです。
コーリーダウニー

それらは排他的ではありません。私はそれをテストしました。
LosManos
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.