2017-09-23 3 views
2

어떻게 생성자에서 get-only 자동 속성을 설정할 수 있습니까? 아래의 코드는 생성자에서 속성을 설정하는 방법을 보여줍니다. 그러나 리플렉션을 사용하면 실제로 장면 뒤에 setter가 없다는 것을 보여줍니다. setter 메서드가 IL에도 존재하지 않으면 생성자 호출에서 어떻게 설정됩니까?C# setter가없는 속성 - 생성자에서 set을 가져 오는 방법은 무엇입니까?

void Main() 
{ 
    var obj = new GetOnlyProperty("original value"); 
    Console.WriteLine(obj.Thing); //works, property gets set from ctor 

    //get the set method with reflection, is it just hidden..? 
    //nope, null reference exception 
    typeof(GetOnlyProperty) 
     .GetProperty("Thing", BindingFlags.Instance | BindingFlags.Public) 
     .GetSetMethod() 
     .Invoke(obj, new object[]{"can't set me to this, setter doen't exist!"}); 
} 

public class GetOnlyProperty 
{ 
    public string Thing { get; } 

    public GetOnlyProperty(string thing) 
    { 
     Thing = thing; 
    } 
} 
+0

비 추상적 자동 속성 필드를 설정하는 것을 알고 항상 뒷받침 필드를 사용하십시오. 클래스 내부의 속성 설정은 뒷받침 필드 설정으로 변환됩니다. 이벤트는 비슷한 방식으로 작동합니다. – IllidanS4

답변

10

읽기 전용 자동 구현 속성은 컴파일러에서 읽기 전용 필드와 읽기 전용 속성으로 변환됩니다. 생성자의 속성에 대한 할당은 기본 필드에 대한 할당으로 컴파일됩니다.

그래서 여기에 코드 : 당신이 작성했던 것처럼

public class GetOnlyProperty 
{ 
    public string Thing { get; } 

    public GetOnlyProperty(string thing) 
    { 
     Thing = thing; 
    } 
} 

는 IL로 컴파일 :

public class GetOnlyProperty 
{ 
    private readonly string _thing; 
    public string Thing => _thing; 

    public GetOnlyProperty(string thing) 
    { 
     _thing = thing; 
    } 
} 

을 ... 그 _thing 제외하고는 정말 "말할 수없는 이름"을 부여하는 같으면 유효한 C# 식별자가 아닙니다.

+0

철저한 답변뿐만 아니라 Jon Skeet 본인도 직접 대답했습니다! 놀라워요, 고마워요 :) – thisextendsthat

+0

재밌 네요'vb.net'에서 속성 이름'_Thing'에 밑줄을 추가하고 값을 변경하여 "생성 된"필드에 액세스 할 수 있습니다. :) – Fabio

+0

@Fabio : Yikes. 다행스럽게도 C#에서는 ' k__BackingField'와 같은 이름이 주어지며'<>'는 식별자로 사용할 수 없게 만듭니다. –

0

읽기 전용 속성은 한 번에 하나씩 지정해야하기 때문에 값이 항상 유형의 기본값이되고 완전히 쓸모가 없습니다.

이것은 (다른 명백한 이유와 함께) 읽기 전용 필드에 값을 할당하기위한 생성자입니다.

+0

내 질문은 _how_입니다. 일리노이에서 setter 메서드가 존재하지 않는다면 어떻게됩니까? 어떻게 생성자가 속성에 대한 호출을 실제로 작동합니까, 아래 커버. – thisextendsthat

2

읽기 전용 속성 (get only)에는 뒷부분에 readonly이라는 필드가 있습니다.이 필드는 아마 알고있는 것처럼 생성자에서만 설정할 수 있습니다.

object Property { get; }

을 따라서 할 때이

private readonly object _property; 
public object get_Property(){return _property;} 

로 변환하고 컴파일러는 생성자의 속성을 설정하면 직접

관련 문제