클래스의 속성 목록을 얻는 방법?


답변:


797

반사; 예를 들어 :

obj.GetType().GetProperties();

유형의 경우 :

typeof(Foo).GetProperties();

예를 들면 다음과 같습니다.

class Foo {
    public int A {get;set;}
    public string B {get;set;}
}
...
Foo foo = new Foo {A = 1, B = "abc"};
foreach(var prop in foo.GetType().GetProperties()) {
    Console.WriteLine("{0}={1}", prop.Name, prop.GetValue(foo, null));
}

피드백을 따르는 중 ...

  • 정적 속성 값을 얻으려면 null첫 번째 인수로 전달 하십시오.GetValue
  • 비공개 속성을 보려면 (예를 들어) GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)(모든 퍼블릭 / 프라이빗 인스턴스 속성을 반환)을 사용하십시오.

13
완전성을 위해 동적 런타임 속성을 허용하는 ComponentDescriptor.GetProperties (...)에 의해 노출되는 ComponentModel도 있습니다 (반사는 컴파일 타임에 수정 됨).
Marc Gravell

5
제안 : 보호 / 개인 / 정적 / 상속 속성을 포함하도록 답변을 확장하십시오.
Richard

1
표시하는 foreach 문은 다음과 같은 속성을 얻으려는 클래스 내에서도 작동합니다.
halfpastfour.am

추가 의견이 명시된 방식에서 명확하지는 않지만 3 개의 플래그를 모두 사용하면 internal속성도 얻을 수 있습니다. 어쩌면 나는 private/ non-public구문 에 매달린 유일한 사람 입니까?
brichins

1
@Tadej 어떤 프레임 워크를 타겟팅하고 있습니까? 당신이 .NET 코어를 사용하는 경우 당신은 당신이이 있는지 확인해야 할 using System.Reflection지침과 System.Reflection.TypeExtensions이 확장 방법을 통해 누락 된 API 표면을 제공합니다 - 참조 패키지
마크 Gravell

91

리플렉션 을 사용하여 이렇게 할 수 있습니다 : (내 라이브러리에서-이름과 값을 얻습니다)

public static Dictionary<string, object> DictionaryFromType(object atype)
{
    if (atype == null) return new Dictionary<string, object>();
    Type t = atype.GetType();
    PropertyInfo[] props = t.GetProperties();
    Dictionary<string, object> dict = new Dictionary<string, object>();
    foreach (PropertyInfo prp in props)
    {
        object value = prp.GetValue(atype, new object[]{});
        dict.Add(prp.Name, value);
    }
    return dict;
}

색인이있는 속성에는이 기능이 작동하지 않습니다.

public static Dictionary<string, object> DictionaryFromType(object atype, 
     Dictionary<string, object[]> indexers)
{
    /* replace GetValue() call above with: */
    object value = prp.GetValue(atype, ((indexers.ContainsKey(prp.Name)?indexers[prp.Name]:new string[]{});
}

또한 공용 속성 만 얻으려면 : ( BindingFlags enum의 MSDN 참조 )

/* replace */
PropertyInfo[] props = t.GetProperties();
/* with */
PropertyInfo[] props = t.GetProperties(BindingFlags.Public)

이것은 익명 형식에서도 작동합니다!
그냥 이름을 얻으려면 :

public static string[] PropertiesFromType(object atype)
{
    if (atype == null) return new string[] {};
    Type t = atype.GetType();
    PropertyInfo[] props = t.GetProperties();
    List<string> propNames = new List<string>();
    foreach (PropertyInfo prp in props)
    {
        propNames.Add(prp.Name);
    }
    return propNames.ToArray();
}

그리고 그것은 값에 대해 거의 동일하거나 다음을 사용할 수 있습니다.

GetDictionaryFromType().Keys
// or
GetDictionaryFromType().Values

그러나 그것은 조금 느리다. 나는 상상할 것이다.


...하지만 atype.GetProperty (prp.Name)은 prp를 반환합니까?
Marc Gravell

5
연결된 MSDN 기사에 따르면 공개 속성 비트와 관련하여 "참고 공용 또는 비공개와 함께 인스턴스 또는 정적을 지정해야합니다. 그렇지 않으면 멤버가 반환되지 않습니다." 따라서 샘플 코드는 다음과 같아야합니다. t.GetProperties(BindingFlags.Instance | BindingFlags.Public)또는t.GetProperties(BindingFlags.Static | BindingFlags.Public)
Carl Sharman

코드를 찾지 않고, 반성과 와우에 대한 설명을 찾고 있었으므로 대단히 감사합니다! 이것을 일반적으로 만들어라. 그러면 당신은 또한 당신의 프로그램이 초능력을 가지고 있다고 말할 수도있다;)
Jaquarh

37
public List<string> GetPropertiesNameOfClass(object pObject)
{
    List<string> propertyList = new List<string>();
    if (pObject != null)
    {
        foreach (var prop in pObject.GetType().GetProperties())
        {
            propertyList.Add(prop.Name);
        }
    }
    return propertyList;
}

이 기능은 클래스 속성 목록을 가져 오기위한 것입니다.


7
이것을 사용하도록 변경하고 싶을 수도 있습니다 yield return. 큰 문제는 아니지만 더 나은 방법입니다.
Matthew Haugen

1
반사가 포함되지 않은 유일한 답변이기 때문에 나는 이것을 좋아한다 .

9
그러나 그럼에도 불구하고 여전히 반사를 사용합니다 .
GGG

2
나는 이것이 훨씬 더 좋다고 생각한다 pObject.GetType (). GetProperties (). Select (p => p.Name)
실망

23

System.Reflection네임 스페이스를 Type.GetProperties()mehod 와 함께 사용할 수 있습니다 .

PropertyInfo[] propertyInfos;
propertyInfos = typeof(MyClass).GetProperties(BindingFlags.Public|BindingFlags.Static);

23

@MarcGravell의 답변을 바탕으로 Unity C #에서 작동하는 버전이 있습니다.

ObjectsClass foo = this;
foreach(var prop in foo.GetType().GetProperties()) {
    Debug.Log("{0}={1}, " + prop.Name + ", " + prop.GetValue(foo, null));
}

8

그게 내 해결책이야

public class MyObject
{
    public string value1 { get; set; }
    public string value2 { get; set; }

    public PropertyInfo[] GetProperties()
    {
        try
        {
            return this.GetType().GetProperties();
        }
        catch (Exception ex)
        {

            throw ex;
        }
    }

    public PropertyInfo GetByParameterName(string ParameterName)
    {
        try
        {
            return this.GetType().GetProperties().FirstOrDefault(x => x.Name == ParameterName);
        }
        catch (Exception ex)
        {

            throw ex;
        }
    }

    public static MyObject SetValue(MyObject obj, string parameterName,object parameterValue)
    {
        try
        {
            obj.GetType().GetProperties().FirstOrDefault(x => x.Name == parameterName).SetValue(obj, parameterValue);
            return obj;
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }
}

6

반사를 사용할 수 있습니다.

Type typeOfMyObject = myObject.GetType();
PropertyInfo[] properties =typeOfMyObject.GetProperties();

3

나는 또한 이런 종류의 요구 사항에 직면하고 있습니다.

이 토론에서 또 다른 아이디어를 얻었습니다.

Obj.GetType().GetProperties()[0].Name

속성 이름도 표시됩니다.

Obj.GetType().GetProperties().Count();

이것은 많은 속성을 보여줍니다.

모두 감사합니다. 이것은 좋은 토론입니다.


3

@lucasjones 답변이 개선되었습니다. 그의 답변 후에 주석 섹션에 언급 된 개선 사항이 포함되었습니다. 누군가가 이것을 유용하게 사용하기를 바랍니다.

public static string[] GetTypePropertyNames(object classObject,  BindingFlags bindingFlags)
{
    if (classObject == null)
    {
        throw new ArgumentNullException(nameof(classObject));
    }

        var type = classObject.GetType();
        var propertyInfos = type.GetProperties(bindingFlags);

        return propertyInfos.Select(propertyInfo => propertyInfo.Name).ToArray();
 }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.