2014-07-04 2 views
5

나는 주제에 this article을 발견하고 시도 다음 C#을 - 속성 생성자에서 던지는 예외

public class FailerAttr : Attribute { 
    public FailerAttr(string s) { 
     throw new Exception("I should definitely fail!"); 
    } 
} 

그리고 단위 테스트 프로젝트의

나는 다음과 같은 한 :

using Microsoft.VisualStudio.TestTools.UnitTesting; 

[TestClass] 
public class Test { 
    [TestMethod] 
    public void GoFail() { 
     // Make sure attribute will get initialized 
     new Failer(); 
    } 

    private class Failer { 
     [FailerAttr("")] 
     public int Prop { get; set; } 
    } 
} 

나는 테스트를 실행하면 성공합니다. 따라서 질문은 다음과 같습니다.

  1. 왜 실패하지 않습니까?
  2. 속성에서 예외를 던지는 것은 정말 나쁜 생각입니까? 왜냐하면 나는 내가 필요하다고 생각하기 때문이다.

일부 환경 정보는 (단지의 경우는 관련이) :

  • 단위 테스트 ReSharper에서의 단위 테스트 러너 (R 번호의 v8.2.0.2160)
  • 비주얼 스튜디오 v11.0.61030를 통해 실행됩니다. 0
+0

리플렉션을 사용하여 속성을 가져올 수 있습니까? –

+0

@KarelFrajtak 확실하지 않습니다. 아직 시도하지 않았습니다. 잠시 후에 다시 시도 할 것입니다. – Dethariel

+3

당신의 코멘트'// 속성이 초기화 될지 확인하십시오'는 거짓입니다. 이 속성은 속성을 조사 할 때 (일반적으로 리플렉션을 통해) 생성됩니다. – Bun

답변

9

속성은 런타임에 사용할 수있는 클래스 정의의 일부이므로 (geekspeak에서는 "메타 데이터"라고도 함) CLR은 프로그램의 일부에서 해당 속성을 요청하지 않으면 인스턴스를 생성하지 않습니다. 이것은 의미가 있습니다 : 왜 아무도 액세스하지 못하도록 CPU 사이클을 낭비하고 있습니까?

때문에이 속성을 요청하지 않는 한 생성자의 실행은 결코 일어나지 않습니다.

var attr = Attribute.GetCustomAttribute(typeof(Failer).GetProperty("Prop"), typeof(FailerAttr)); 

이 코드는 CLR이 예외를 트리거 FailerAttr을 인스턴스화합니다 :

여기에 하나 개의 프로그램을 만들 것 속성을 요청하는 방법이 실패 할 수 있습니다.

Demo on ideone.

당신은 속성의 유형을 모르는 경우, 당신은 모든이 호출로 한 번에 속성을 검색 할 수 있습니다

var allAttributes = Attribute.GetCustomAttributes(typeof(Failer).GetProperty("Prop")); 

이뿐만 아니라 (demo) 예외가 발생합니다.

+0

실패를 달성하는 방법에 대한 코드 샘플의 답변으로 표시했습니다. 고마워요! – Dethariel

+0

정말 관련이 없지만 .NET 4.5 이상을 대상으로하는 경우 일반적인 확장 메서드 ('using System.Reflection;')가 있으므로'typeof (Failer) .GetProperty ("Prop")라고 말할 수 있습니다. GetCustomAttribute (단일 또는 널) 또는 'typeof (Failer) .GetProperty ("Prop"). GetCustomAttributes ()'(모든 발생 가능, 비어 있음). –

+0

@JeppeStigNielsen 우리는 4.5.1로 이동하고 있으며, 4.0에서 내 확장 메서드를 사용하고 있습니다. 조언 해 주셔서 감사합니다. – Dethariel

7

속성이 실행 가능 코드로 변환되지 않고 메타 데이터로 변환됩니다.

정상적인 실행 중에는 이와 같은 메타 데이터가 사용되지 않으며, 리플렉션을 통해 메타 데이터를 사용하기 시작한 경우에만 속성 유형이 다시 재생됩니다.

생성자 또는 속성의 코드가 컴파일 중에 실행되지 않습니다. 대신 생성자에 대한 유형 및 매개 변수는 메타 데이터에 직렬화되며 리플렉션을 사용하여 검사 할 때만 생성자가 실제로 실행됩니다.

즉, 컴파일 할 때이 오류가 발생하면이를 수행 할 수 없습니다.

리플렉션을 사용하여 특성을 찾으려는 경우 특성 개체가 메타 데이터에서 deserialize됨에 따라 생성자가 호출 될 수도 있고 호출되지 않을 수도 있지만 식별자에 적용하는 것만으로는 호출되지 않습니다.

+0

그래서 typeof (Failer) .GetProperty ("Prop")와 같이 속성을 리플렉션을 통해 반입 할 때 생성자 코드가 실행되는지 여부 (또는 의존 여부). GetCustomAttributes() –

+0

해당 부분을 사용할 때 실행되지만 컴파일시에는 실행되지 않습니다. –