특정 속성의 PropertyInfo를 얻는 방법은 무엇입니까?


82

특정 속성에 대한 PropertyInfo를 얻고 싶습니다. 다음을 사용할 수 있습니다.

foreach(PropertyInfo p in typeof(MyObject).GetProperties())
{
    if ( p.Name == "MyProperty") { return p }
}

하지만 다음과 비슷한 방법이 있어야합니다.

typeof(MyProperty) as PropertyInfo

거기 있어요? 아니면 유형이 안전하지 않은 문자열 비교를 계속하고 있습니까?

건배.

답변:


61

nameof()C # 6의 일부이며 Visual Studio 2015에서 사용할 수 있는 new 연산자를 사용할 수 있습니다 . 자세한 내용은 여기 .

예를 들어 다음을 사용합니다.

PropertyInfo result = typeof(MyObject).GetProperty(nameof(MyObject.MyProperty));

컴파일러는 nameof(MyObject.MyProperty)"MyProperty"문자열 로 변환 되지만 Visual Studio, ReSharper 등은 nameof()값 을 리팩터링하는 방법을 알고 있기 때문에 문자열을 변경하지 않고도 속성 이름을 리팩터링 할 수 있다는 이점을 얻을 수 있습니다.


1
당신의 예제가 PropertyInfo result =대신에 시작된다면 틀림없이 조금 더 명확 할 것입니다 var result =.
DavidRR

134

Expression문자열을 사용하지 않는 lambdas /와 함께 .NET 3.5 방법이 있습니다.

using System;
using System.Linq.Expressions;
using System.Reflection;

class Foo
{
    public string Bar { get; set; }
}
static class Program
{
    static void Main()
    {
        PropertyInfo prop = PropertyHelper<Foo>.GetProperty(x => x.Bar);
    }
}
public static class PropertyHelper<T>
{
    public static PropertyInfo GetProperty<TValue>(
        Expression<Func<T, TValue>> selector)
    {
        Expression body = selector;
        if (body is LambdaExpression)
        {
            body = ((LambdaExpression)body).Body;
        }
        switch (body.NodeType)
        {
            case ExpressionType.MemberAccess:
                return (PropertyInfo)((MemberExpression)body).Member;
            default:
                throw new InvalidOperationException();
        }
    }
}

좋은 솔루션이지만 불행히도 .NET3.5를 사용하지 않습니다. 그래도 틱!
tenpn

1
2.0에서는 Vojislav Stojkovic의 답변이 가장 가깝습니다.
Marc Gravell

4
한 가지 질문 : .Body 속성을 추출하기 전에 "body is LambdaExpression"에 대한 테스트가있는 이유는 무엇입니까? 선택기가 항상 LambdaExpression이 아닙니까?
tigrou

@tigrou 아마도 그냥 감독, 그리고 아마도 단지 나에 대해 일한 기존 코드 빌리Expression
마크 Gravell

@MarcGravell이 구현은 그다지 건전하지 않습니다. 의 경우 올바른 속성 정보를 얻지 못합니다 PropertyHelper<Derived>.GetProperty(x => x.BaseProperty);. stackoverflow.com/questions/6658669/…
nawfal 2013-12-13

13

다음과 같이 할 수 있습니다.

typeof(MyObject).GetProperty("MyProperty")

그러나 C #에는 "기호"유형이 없기 때문에 문자열 사용을 피하는 데 도움이되는 것은 없습니다. 그런데 왜 이것을 안전하지 않다고 부르나요?


38
컴파일 타임에 평가되지 않기 때문에? 속성 이름을 변경하거나 문자열을 오타하면 코드가 실행될 때까지 알 수 없습니다.
tenpn

1

리플렉션은 런타임 유형 평가에 사용됩니다. 따라서 컴파일 타임에 문자열 상수를 확인할 수 없습니다.


5
그것이 OP가 피하려고하는 것입니다. 이것이 질문에 대한 대답인지 확실하지 않습니다.
nawfal

컴파일 시간 대 런타임 및 OP의 원래 의도와 관련하여 좋은 점은 하드 코딩 된 문자열을 피하는 것이 여전히 가장 깨끗한 해결책 인 것처럼 보입니다. 오타 가능성을 피하고 더 쉽게 리팩토링 할 수 있으며 더 깨끗한 코드 스타일을 만듭니다.
Brian Sweeney
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.