리플렉션을 사용하여 정적 속성을 얻는 방법


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를 사용한다는 점에서 비슷합니다. 정적 또는 인스턴스 등 Public 멤버를 가져올 수있는 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
이 두 null은 어떤 변수에 해당합니까? 가능하다면 명명 된 인수를 사용하여 어떻게 작성 하시겠습니까? 감사.
Hamish Grubijan

내부 정적 클래스의 경우?
Kiquenet

이것이 최선의 선택입니다. 제 생각에는 답으로 선택해야합니다.
c0y0teX

8
p.GetValue(null);너무 작동합니다. 두 번째 null는 필요하지 않습니다.
Chrono

멋지네요. 목표는 이름 인수를 기반으로 속성을 가져 오는 것이 었습니다.이를 달성하기 위해 속성을 반복하고 싶지는 않습니다.
Corey Downie

42

이것은 C #이지만 아이디어를 제공해야합니다.

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

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

(또는 NonPublic 및 Static에만 필요)


3
제 경우에는이 두 플래그 만 사용하면 효과가 없었습니다. .FlattenHierarchy 플래그도 사용해야했습니다.
Corey Downie

3
@CoreyDownie가 동의했습니다. BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy나를 위해 일한 유일한 것입니다.
Jonathon Reinhart

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.

'new'리플렉션에서 유형 (기본 클래스 제외)의 정적 속성을 얻으려면 다음과 같이해야합니다.

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


    }
}

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.