.NET의 속성은 무엇입니까?


답변:


146

메타 데이터. 객체 / 방법 / 속성에 대한 데이터

예를 들어, DisplayOrder라는 속성을 선언하여 UI에 속성을 표시 할 순서를 쉽게 제어 할 수 있습니다. 그런 다음 클래스에 추가하고 속성을 추출하고 UI 요소를 적절하게 정렬하는 GUI 구성 요소를 작성할 수 있습니다.

public class DisplayWrapper
{
    private UnderlyingClass underlyingObject;

    public DisplayWrapper(UnderlyingClass u)
    {
        underlyingObject = u;
    }

    [DisplayOrder(1)]
    public int SomeInt
    {
        get
        {
            return underlyingObject .SomeInt;
        }
    }

    [DisplayOrder(2)]
    public DateTime SomeDate
    {
        get
        {
            return underlyingObject .SomeDate;
        }
    }
}

따라서 사용자 정의 GUI 구성 요소로 작업 할 때 SomeDate 전에 SomeInt가 항상 표시되도록합니다.

그러나 직접 코딩 환경 외부에서 가장 일반적으로 사용되는 것을 볼 수 있습니다. 예를 들어 Windows Designer는이를 광범위하게 사용하므로 사용자 지정 개체를 처리하는 방법을 알고 있습니다. BrowsableAttribute를 다음과 같이 사용하십시오.

[Browsable(false)]
public SomeCustomType DontShowThisInTheDesigner
{
    get{/*do something*/}
}

예를 들어 디자인 타임에 디자이너가 속성 창의 사용 가능한 속성에이 속성을 나열하지 않도록 지시합니다.

당신은 또한 Reflection.Emit를이나 런타임 작업 (예 : 포스트 - 샤프)를 사전 컴파일 작업, 코드 생성을 위해 그들을 사용합니다. 예를 들어, 코드를 작성하고 호출 할 때마다 호출마다 투명하게 래핑되는 프로파일 링을위한 약간의 코드를 작성할 수 있습니다. 특정 방법에 배치 한 속성을 통해 타이밍을 "선택 해제"할 수 있습니다.

public void SomeProfilingMethod(MethodInfo targetMethod, object target, params object[] args)
{
    bool time = true;
    foreach (Attribute a in target.GetCustomAttributes())
    {
        if (a.GetType() is NoTimingAttribute)
        {
            time = false;
            break;
        }
    }
    if (time)
    {
        StopWatch stopWatch = new StopWatch();
        stopWatch.Start();
        targetMethod.Invoke(target, args);
        stopWatch.Stop();
        HandleTimingOutput(targetMethod, stopWatch.Duration);
    }
    else
    {
        targetMethod.Invoke(target, args);
    }
}

그것들을 선언하는 것은 쉽습니다. 속성에서 상속받은 클래스를 만드십시오.

public class DisplayOrderAttribute : Attribute
{
    private int order;

    public DisplayOrderAttribute(int order)
    {
        this.order = order;
    }

    public int Order
    {
        get { return order; }
    }
}

그리고 속성을 사용할 때 접미사 "속성"을 생략 할 수 있다는 점을 기억하십시오. 컴파일러가이를 추가합니다.

참고 : 속성은 자체적으로 아무 것도하지 않습니다 . 속성을 사용하는 다른 코드가 필요합니다. 때때로 그 코드는 당신을 위해 쓰여졌지만 때때로 당신은 그것을 직접 써야합니다. 예를 들어 C # 컴파일러는 일부 및 특정 프레임 워크에서 일부 프레임 워크를 사용합니다 (예 : NUnit은 클래스에서 [TestFixture]를 찾고 어셈블리를로드 할 때 테스트 메서드에서 [Test])합니다.
따라서 사용자 정의 속성을 만들 때 코드의 동작에 전혀 영향을 미치지 않습니다. 속성을 확인 (반사를 통해)하는 다른 부분을 작성하고 그에 따라 행동해야합니다.


32
: 무엇의 가치, 이것은 (내장) 모든 목록 .NET은 속성입니다 msdn.microsoft.com/en-us/library/aa311259(VS.71).aspx
wprl

1
"SomeProfilingMethod"를 속성으로 어떻게 사용 하시겠습니까?
RayLoveless

@RayLoveless는 속성이 아니라 SomeProfilingMethod는 프로파일 링 속성을 찾고있는 계측 코드입니다. 특히이 예에서는 "opt-in"속성이 아닌 "opt-out"속성 (NoTimingAttribute)을 찾도록했습니다. 아이디어는 모든 것을 곱한다는 것입니다.
Quibblesome

@Quibblesome 당신은 "속성들은 스스로 아무것도하지 않습니다- 그것들을 사용하기 위해 다른 코드 가 필요 합니다. (컴파일러는 커플에 관심이 있고, 다른 프레임 워크는 일부를 사용합니다.) 속성을 생성하는 것만으로 코드의 동작에 영향을 미치지 않습니다- "반사를 통해"속성을 확인하고 그 속성에 작용하는 다른 부분을 작성해야합니다. " (또는 괜찮 으면 할 수 있습니다). 많은 사람들이 속성이 마술처럼 작동하기를 기대하며 여기에 어떤 대답도 명확하지 않습니다. (또는 그냥 stackoverflow.com/questions/4879521/…에 연결 )
Alexei Levenkov

Bing 사용을 중지 한 경우에만 해당됩니다. 아냐 j / k 주로 Duckinguck을 주로 Bing iirc를 사용하는 기본으로 사용합니다. :)
Quibblesome 2019

36

많은 사람들이 대답했지만 지금까지 아무도 언급하지 않았습니다 ...

속성은 리플렉션과 함께 많이 사용됩니다. 반사는 이미 꽤 느립니다.

그것은이다 매우 가치 있는 것으로 사용자 정의 속성을 표시 sealed자신의 런타임 성능을 개선하기 위해 클래스.

또한 이러한 속성을 사용하는 것이 적절한 위치를 고려하고이를 통해 속성을 나타내는 속성 (!)을 지정하는 것이 AttributeUsage좋습니다. 사용 가능한 속성 사용법 목록은 다음을 놀라게 할 수 있습니다.

  • 어셈블리
  • 기준 치수
  • 수업
  • 구조
  • 열거 형
  • 건설자
  • 방법
  • 특성
  • 행사
  • 상호 작용
  • 모수
  • 대리자
  • ReturnValue
  • GenericParameter
  • 모두

AttributeUsage 속성이 AttributeUsage 속성 서명의 일부인 것도 멋집니다. 순환 종속성에 대한 우와!

[AttributeUsageAttribute(AttributeTargets.Class, Inherited = true)]
public sealed class AttributeUsageAttribute : Attribute

13

속성은 클래스에 태그를 지정하기위한 일종의 메타 데이터입니다. 예를 들어 WinForms에서 툴바에서 컨트롤을 숨기는 등의 경우가 종종 있지만, 다른 클래스의 인스턴스가 특정 방식으로 작동 할 수 있도록 자체 응용 프로그램에서 구현할 수 있습니다.

속성을 작성하여 시작하십시오.

[AttributeUsage(AttributeTargets.Class, AllowMultiple=false, Inherited=true)]
public class SortOrderAttribute : Attribute
{
    public int SortOrder { get; set; }

    public SortOrderAttribute(int sortOrder)
    {
        this.SortOrder = sortOrder;
    }
}

모든 속성 클래스의 접미사 "Attribute"가 유효해야합니다.
이 작업이 완료되면 속성을 사용하는 클래스를 작성하십시오.

[SortOrder(23)]
public class MyClass
{
    public MyClass()
    {
    }
}

이제 다음을 수행하여 특정 클래스 SortOrderAttribute(있는 경우)를 확인할 수 있습니다 .

public class MyInvestigatorClass
{
    public void InvestigateTheAttribute()
    {
        // Get the type object for the class that is using
        // the attribute.
        Type type = typeof(MyClass);

        // Get all custom attributes for the type.
        object[] attributes = type.GetCustomAttributes(
            typeof(SortOrderAttribute), true);

        // Now let's make sure that we got at least one attribute.
        if (attributes != null && attributes.Length > 0)
        {
            // Get the first attribute in the list of custom attributes
            // that is of the type "SortOrderAttribute". This should only
            // be one since we said "AllowMultiple=false".
            SortOrderAttribute attribute = 
                attributes[0] as SortOrderAttribute;

            // Now we can get the sort order for the class "MyClass".
            int sortOrder = attribute.SortOrder;
        }
    }
}

이에 대한 자세한 내용을 보려면 MSDN에 대한 설명이 항상 좋습니다.
이것이 도움이 되었기를 바랍니다.


5

속성은 코드의 객체에 적용 할 수있는 약간의 기능을 포함하는 클래스입니다. 하나를 만들려면 System.Attribute에서 상속되는 클래스를 만듭니다.

그들이 좋은 것에 관해서는 ... 거의 무한한 용도가 있습니다.

http://www.codeproject.com/KB/cs/dotnetattributes.aspx


1
여기서 "기능"은 잘못된 단어입니다. 그것들은 기능이 아니라 메타 데이터입니다
Marc Gravell

5

속성은 클래스, 메서드 또는 어셈블리에 적용되는 메타 데이터와 같습니다.

그것들은 많은 것들에 좋습니다 (디버거 시각화, 사물을 쓸모없는 것으로 표시, 사물을 직렬화 가능으로 표시, 목록은 끝이 없습니다).

자신 만의 커스텀을 만드는 것은 파이처럼 쉽습니다. 여기에서 시작하십시오 :

http://msdn.microsoft.com/en-us/library/sw480ze8(VS.71).aspx


5

현재 작업중 인 프로젝트에는 다양한 취향의 UI 객체 세트와 DevStudio의 양식 디자이너와 같은 기본 응용 프로그램에서 사용할 페이지를 만들기 위해 이러한 객체를 조립하는 편집기가 있습니다. 이러한 개체는 자체 어셈블리에 존재하며 각 개체는 파생 클래스 UserControl이며 사용자 지정 특성이 있습니다. 이 속성은 다음과 같이 정의됩니다.

[AttributeUsage (AttributeTargets::Class)]
public ref class ControlDescriptionAttribute : Attribute
{
public:
  ControlDescriptionAttribute (String ^name, String ^description) :
    _name (name),
    _description (description)
  {
  }

  property String ^Name
  {
    String ^get () { return _name; }
  }

  property String ^Description
  {
    String ^get () { return _description; }
  }

private:
  String
    ^ _name,
    ^ _description;
};

나는 이것을 다음과 같은 수업에 적용합니다.

[ControlDescription ("Pie Chart", "Displays a pie chart")]
public ref class PieControl sealed : UserControl
{
  // stuff
};

이전 포스터가 말한 것입니다.

이 속성을 사용하기 위해 편집기에는 Generic::List <Type>컨트롤 유형 이 포함되어 있습니다. 컨트롤의 인스턴스를 만들기 위해 사용자가 페이지에서 끌어서 놓을 수있는 목록 상자가 있습니다. 목록 상자를 채우려면 ControlDescriptionAttribute컨트롤에 대한을 얻고 목록에서 항목을 작성하십시오.

// done for each control type
array <Object ^>
  // get all the custom attributes
  ^attributes = controltype->GetCustomAttributes (true);

Type
  // this is the one we're interested in
  ^attributetype = ECMMainPageDisplay::ControlDescriptionAttribute::typeid;

// iterate over the custom attributes
for each (Object ^attribute in attributes)
{
  if (attributetype->IsInstanceOfType (attribute))
  {
    ECMMainPageDisplay::ControlDescriptionAttribute
      ^description = safe_cast <ECMMainPageDisplay::ControlDescriptionAttribute ^> (attribute);

    // get the name and description and create an entry in the list
    ListViewItem
      ^item = gcnew ListViewItem (description->Name);

    item->Tag = controltype->Name;
    item->SubItems->Add (description->Description);

    mcontrols->Items->Add (item);
    break;
  }
}

참고 : 위의 C ++ / CLI이지만 C #으로 변환하는 것은 어렵지 않습니다 (예, C ++ / CLI는 혐오이지만 내가 사용해야 할 것은 :-()

대부분의 경우 속성을 배치 할 수 있으며 사전 정의 된 속성의 전체 범위가 있습니다. 위에서 언급 한 편집기는 속성 및 속성 편집 방법을 설명하는 속성의 사용자 지정 특성을 찾습니다.

일단 당신이 모든 아이디어를 얻으면, 당신은 그들없이 어떻게 살았는지 궁금해 할 것입니다.


4

앞서 언급했듯이 속성은 비교적 쉽게 만들 수 있습니다. 작업의 다른 부분은이를 사용하는 코드를 작성하는 것입니다. 대부분의 경우 런타임시 리플렉션을 사용하여 속성 또는 해당 속성의 존재 여부에 따라 동작을 변경합니다. 컴파일 된 코드에서 속성을 검사하여 일종의 정적 분석을 수행하는 시나리오도 있습니다. 예를 들어, 매개 변수는 널이 아닌 것으로 표시 될 수 있으며 분석 도구는이를 힌트로 사용할 수 있습니다.

속성을 사용하고 적절한 시나리오를 사용하는 것은 많은 작업입니다.


3

속성은 본질적으로 유형 에 첨부하려는 데이터 비트 (클래스, 메소드, 이벤트, 열거 형 등)입니다.

아이디어는 실행시 다른 유형의 / 프레임 워크 / 도구 쿼리 것입니다 귀하의 속성에 정보를 입력하고 그것을 바탕으로 행동한다.

예를 들어 Visual Studio는 타사 컨트롤의 특성을 쿼리하여 디자인시 속성 창에 컨트롤의 속성을 표시 할 수 있습니다.

Aspect Oriented Programming에서 속성을 사용하여 오브젝트를 장식하고 오브젝트의 비즈니스 로직에 영향을주지 않고 오브젝트에 유효성 검증, 로깅 등을 추가하는 속성을 기반으로 런타임에 오브젝트를 주입 / 조작 할 수 있습니다.



2

속성 작성을 시작하려면 C # 소스 파일을 열고 attribute[TAB]을 입력 하고 누르십시오. 새 속성의 템플릿으로 확장됩니다.


6
질문에 어떻게 대답합니까? 답이 아닌 설명이어야합니다.
gdoron 모니카 지원하고

1

속성은 또한 Aspect Oriented Programming에도 사용됩니다. 이에 대한 예는 PostSharp 프로젝트를 확인하십시오 .

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