클래스에 속성이 있는지 확인


82

클래스에 속성이 있는지 확인하려고 시도했습니다.

public static bool HasProperty(this object obj, string propertyName)
{
    return obj.GetType().GetProperty(propertyName) != null;
}

첫 번째 테스트 방법이 통과하지 못하는 이유를 이해할 수 없습니다.

[TestMethod]
public void Test_HasProperty_True()
{
    var res = typeof(MyClass).HasProperty("Label");
    Assert.IsTrue(res);
}

[TestMethod]
public void Test_HasProperty_False()
{
    var res = typeof(MyClass).HasProperty("Lab");
    Assert.IsFalse(res);
}

4
에서 관련 코드를 게시 해 주시겠습니까 MyClass?
nattyddubbs

답변:


126

방법은 다음과 같습니다.

public static bool HasProperty(this object obj, string propertyName)
{
    return obj.GetType().GetProperty(propertyName) != null;
}

이것은 모든 것의object 기본 클래스에 확장을 추가합니다 . 이 확장을 호출하면 다음과 같이 전달됩니다 .Type

var res = typeof(MyClass).HasProperty("Label");

귀하의 방법은 예상 예를 클래스가 아닌의를 Type. 그렇지 않으면 본질적으로

typeof(MyClass) - this gives an instanceof `System.Type`. 

그때

type.GetType() - this gives `System.Type`
Getproperty('xxx') - whatever you provide as xxx is unlikely to be on `System.Type`

로 @PeterRitchie 올바르게 코드가 재산을 찾고있는이 시점에서, 지적 LabelSystem.Type. 해당 속성이 존재하지 않습니다.

해결책은

a) 확장에 MyClass 인스턴스 를 제공합니다 .

var myInstance = new MyClass()
myInstance.HasProperty("Label")

b) 내선을 System.Type

public static bool HasProperty(this Type obj, string propertyName)
{
    return obj.GetProperty(propertyName) != null;
}

typeof(MyClass).HasProperty("Label");

2
즉, 코드가 'Type.Label , not MyClass.Label'을 찾고 있습니다.
Peter Ritchie 2013 년

확장 System.Type에 어떻게 이것을 넣을 수 있습니까? 실행할 코드는 어디에 있습니까?
Demodave

1
@Demodave-확장 메서드는 공용 정적 클래스에 있습니다. 자세한 내용은 여기를 참조하십시오. msdn.microsoft.com/en-GB/library/bb383977.aspx
Jamiec

이 오류가 발생하면 "Type에 GetProperty에 대한 정의가 포함되어 있지 않습니다."다음을 읽으십시오. stackoverflow.com/questions/7858469/…
Tadej

26

이것은 다른 질문에 답합니다.

OBJECT (클래스 아님)에 속성이 있는지 알아 내려고하면

OBJECT.GetType().GetProperty("PROPERTY") != null

속성이 존재하는 경우에만 true를 반환합니다.

제 경우에는 ASP.NET MVC 부분보기에 있었고 속성이 존재하지 않거나 속성 (부울)이 true이면 무언가를 렌더링하고 싶었습니다.

@if ((Model.GetType().GetProperty("AddTimeoffBlackouts") == null) ||
        Model.AddTimeoffBlackouts)

여기에서 나를 도왔다.

편집 : 요즘에는 nameof문자열로 된 속성 이름 대신 연산자 를 사용하는 것이 현명 할 것입니다 .


nameof연산자 사용과 관련하여 존재하지 않을 수있는 속성의 이름을 가져 오는 것이 작동합니까 (예외가 발생하지 않음)? 원래 질문의 전제는이 속성이 존재하는지 알 수 없다는 것이었기 때문에?
Zoe

그것을 시도하고 명확하게 내 대답을 편집하는 것이 어떻습니까?
Stachu

2

두 가지 가능성이 있습니다.

당신은 정말 Label재산 이 없습니다 .

적절한 GetProperty 오버로드 를 호출 하고 올바른 바인딩 플래그를 전달해야합니다. 예 :BindingFlags.Public | BindingFlags.Instance

속성이 공개되지 않은 BindingFlags.NonPublic경우 사용 사례에 맞는 플래그 또는 다른 플래그 조합을 사용해야합니다. 참조 된 API 문서를 읽고 세부 사항을 찾으십시오.

편집하다:

ooops, 방금 전화를 걸었 GetProperty습니다 typeof(MyClass). typeof(MyClass)이다 Type확실히 더 갖지 않는 Label속성을.


사용되는 기본 바인딩 플래그는 Instance|Public|Staticiirc입니다.
LukeH 2013 년

@LukeH, 확실하지 않아서 '올바른'이라고 쓰고 '예'를 추가 Label했습니다. :) 아마도 사유 재산 일 수 있습니다.
Zdeslav Vojkovic 2013 년

1

수락 된 답변을 입력 할 때 "Type에 GetProperty에 대한 정의가 없습니다"라는 오류가 발생했습니다.

이것이 내가 끝낸 것입니다.

using System.Reflection;

if (productModel.GetType().GetTypeInfo().GetDeclaredProperty(propertyName) != null)
{

}

0

나처럼 구속력이 있다면 :

<%# Container.DataItem.GetType().GetProperty("Property1") != null ? DataBinder.Eval(Container.DataItem, "Property1") : DataBinder.Eval(Container.DataItem, "Property2")  %>

0

왜 이것이 필요한지에 대한 컨텍스트가 확실하지 않으므로 충분한 정보가 반환되지 않을 수 있지만 이것이 내가 할 수 있었던 것입니다.

if(typeof(ModelName).GetProperty("Name of Property") != null)
{
//whatevver you were wanting to do.
}

제 경우에는 양식 제출의 속성을 통해 실행 중이며 항목이 비어있는 경우 사용할 기본값도 있습니다. 따라서 사용할 값이 있는지 알아야했습니다. 모델의 모든 기본값을 접두사로 지정했습니다. 함께 기본 이 시작하는 특성이 있다면 할 필요가 모든 나는 검사가 그래서.

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