[C#] C #에서 필드를 ‘읽기 전용’으로 표시하면 어떤 이점이 있습니까?

멤버 변수를 읽기 전용으로 선언하면 어떤 이점이 있습니까? 수업 기간 동안 누군가가 가치를 변경하는 것을 막거나이 키워드를 사용하면 속도 나 효율성이 향상됩니까?



답변

readonly키워드는 런타임에서 산출되는 값을 멤버 변수 상수를 선언하는 데 사용하지만, 허용된다. 이것은 const수정 자 (modifier)로 선언 된 상수와 다르며 , 컴파일시 값을 설정해야합니다. 를 사용 readonly하면 선언 또는 필드가 속한 개체의 생성자에서 필드 값을 설정할 수 있습니다.

상수를 참조하는 외부 DLL을 다시 컴파일하지 않으려는 경우에도 사용하십시오 (컴파일 시간에 대체되기 때문에).


답변

읽기 전용 필드를 사용하면 성능이 향상되지 않는다고 생각합니다. 객체가 완전히 구성되면 해당 필드가 새로운 값을 가리킬 수 없는지 확인하는 것입니다.

그러나 “읽기 전용”은 런타임에 CLR에 의해 시행되므로 다른 유형의 읽기 전용 의미론과는 매우 다릅니다. readonly 키워드는 CLR에서 확인할 수있는 .initonly로 컴파일됩니다.

이 키워드의 실제 장점은 변경 불가능한 데이터 구조를 생성하는 것입니다. 정의에 의한 불변 데이터 구조는 일단 생성 된 후에는 변경할 수 없습니다. 이를 통해 런타임시 구조의 동작을 쉽게 추론 할 수 있습니다. 예를 들어, 불변의 구조를 다른 임의의 코드 부분으로 전달할 위험이 없습니다. 그들은 그것을 바꿀 수 없으므로 그 구조에 대해 안정적으로 프로그래밍 할 수 있습니다.

다음은 불변성의 이점 중 하나에 대한 좋은 항목입니다. 스레딩


답변

를 사용 readonly하면 성능상의 이점이 없으며 적어도 어느 곳에서도 언급 한 적이 없습니다. 일단 초기화되면 수정을 방지하기 위해 제안한대로 정확하게 수행하기위한 것입니다.

따라서보다 강력하고 읽기 쉬운 코드를 작성하는 데 도움이됩니다. 이와 같은 것의 실질적인 이점은 팀에서 일하거나 유지 보수를 할 때 발생합니다. readonly코드에서 해당 변수의 사용에 대한 계약을 맺는 것과 비슷한 것을 선언 합니다. 같은 다른 키워드와 같은 방법으로 문서를 추가로 생각 internal하거나 private, 당신은 “이 변수가 초기화 후 수정할 수 없습니다”라고하고 있으며, 또한 당신에게있는 거 수행 및을 을.

따라서 클래스를 만들고 readonly의도적으로 일부 멤버 변수 를 표시 하면 나중에 자신이나 다른 팀 멤버가 클래스를 확장하거나 수정할 때 실수를 저지르는 것을 방지 할 수 있습니다. 내 의견으로는, 그것은 가치가있는 이점입니다 (댓글에서 doofledorfer가 언급 한 것처럼 추가 언어 복잡성으로 적은 비용으로).


답변

매우 실용적인 용어로 말하면 :

dll A의 const를 사용하고 dll B가 그 const를 참조하면 해당 const의 값은 dll B로 컴파일됩니다. dll A를 해당 const의 새 값으로 재배치하면 dll B는 여전히 원래 값을 사용합니다.

읽기 전용 인 dll A 및 dll B 참조에서 읽기 전용을 사용하는 경우 해당 읽기 전용은 항상 런타임에 조회됩니다. 이는 dll A를 해당 읽기 전용의 새 값으로 재배치하면 dll B가 해당 새 값을 사용한다는 의미입니다.


답변

컴파일러가 읽기 전용 키워드의 존재 여부에 따라 성능을 최적화 할 수있는 경우가 있습니다.

읽기 전용 필드도 static으로 표시된 경우에만 적용됩니다 . 이 경우 JIT 컴파일러는이 정적 필드가 절대 변경되지 않는다고 가정 할 수 있습니다. JIT 컴파일러는 클래스의 메소드를 컴파일 할 때이를 고려할 수 있습니다.

일반적인 예 : 클래스 에는 생성자에서 초기화 되는 정적 읽기 전용 IsDebugLoggingEnabled 필드가 있을 수 있습니다 (예 : 구성 파일 기반). 실제 메소드가 JIT 컴파일되면 디버그 로깅이 사용 가능하지 않은 경우 컴파일러가 코드의 전체 부분을 생략 할 수 있습니다.

이 최적화가 실제로 현재 버전의 JIT 컴파일러에서 구현되는지 확인하지 않았으므로 이것은 단지 추측입니다.


답변

읽기 전용은 값 자체에만 적용되므로 참조 유형을 사용하는 경우 읽기 전용은 참조가 변경되지 않도록 보호합니다. 인스턴스의 상태는 읽기 전용으로 보호되지 않습니다.


답변

params를 readonly사용하여 생성자 외부 에서 필드를 설정 하는 해결 방법이 있다는 것을 잊지 마십시오 out.

조금 지저분하지만 :

private readonly int _someNumber;
private readonly string _someText;

public MyClass(int someNumber) : this(data, null)
{ }

public MyClass(int someNumber, string someText)
{
    Initialise(out _someNumber, someNumber, out _someText, someText);
}

private void Initialise(out int _someNumber, int someNumber, out string _someText, string someText)
{
    //some logic
}

여기에 대한 추가 토론 : http://www.adamjamesnaylor.com/2013/01/23/Setting-Readonly-Fields-From-Chained-Constructors.aspx