멤버 변수를 읽기 전용으로 선언하면 어떤 이점이 있습니까? 수업 기간 동안 누군가가 가치를 변경하는 것을 막거나이 키워드를 사용하면 속도 나 효율성이 향상됩니까?
readonly
구조 유형의 필드가의 구성원의 호출하기 때문에, 단순히 돌연변이되지 않은 변경 가능한 필드에 비해 성능 저하를 부과 readonly
분야의 복사본을 만들기 위해 컴파일러의 원인이됩니다 값 타입의 필드와 호출을 그것에 회원.
멤버 변수를 읽기 전용으로 선언하면 어떤 이점이 있습니까? 수업 기간 동안 누군가가 가치를 변경하는 것을 막거나이 키워드를 사용하면 속도 나 효율성이 향상됩니까?
readonly
구조 유형의 필드가의 구성원의 호출하기 때문에, 단순히 돌연변이되지 않은 변경 가능한 필드에 비해 성능 저하를 부과 readonly
분야의 복사본을 만들기 위해 컴파일러의 원인이됩니다 값 타입의 필드와 호출을 그것에 회원.
답변:
읽기 전용 필드를 사용하면 성능이 향상되지 않는다고 생각합니다. 객체가 완전히 구성되면 해당 필드가 새로운 값을 가리킬 수 없는지 확인하는 것입니다.
그러나 "읽기 전용"은 런타임에 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가 해당 새 값을 사용한다는 의미입니다.
readonly
필드 에 저장하는 능력이라는이 대답에서 빠졌다고 생각 합니다. a new object();
를 저장할 const
수 없으며 ID를 변경하지 않고 컴파일 타임에 다른 어셈블리에 대한 참조와 같은 값이 아닌 것을 구울 수 없으므로 의미가 있습니다.
컴파일러가 읽기 전용 키워드의 존재 여부에 따라 성능을 최적화 할 수있는 경우가 있습니다.
읽기 전용 필드도 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
out
.
놀랍게도 Jon Skeet이 Noda Time 라이브러리를 테스트 할 때 발견 한 것처럼 읽기 전용은 실제로 코드 속도가 느려질 수 있습니다. 이 경우 20 초 동안 실행 된 테스트는 읽기 전용을 제거한 후 4 초 밖에 걸리지 않았습니다.
readonly struct
C # 7.2 의 유형 인 경우 필드를 비 읽기 전용으로 설정하면 얻을 수있는 이점이 사라집니다.
이 질문에 대답하기 위해 기본 측면 추가 :
set
연산자 를 생략하면 속성을 읽기 전용으로 표현할 수 있습니다 . 따라서 대부분의 경우 readonly
키워드를 속성 에 추가 할 필요가 없습니다 .
public int Foo { get; } // a readonly property
이와 대조적으로 : readonly
유사한 효과를 얻으려면 필드에 키워드가 필요합니다 .
public readonly int Foo; // a readonly field
따라서 어떤 이유로 든 원하는 경우 필드를 속성으로 변경할 필요 readonly
없이 set
연산자없이 속성과 유사한 쓰기 방지 수준을 달성 할 수있는 것처럼 필드를 표시하는 한 가지 이점 이 있습니다.
전용 읽기 전용 배열에주의하십시오. 이것들이 클라이언트로 객체로 노출되면 (내가했던 것처럼 COM interop에 대해이 작업을 수행 할 수 있음) 클라이언트는 배열 값을 조작 할 수 있습니다. 배열을 객체로 반환 할 때는 Clone () 메서드를 사용하십시오.
ReadOnlyCollection<T>
배열 대신에 노출하십시오 .
ImmutableArray<T>
부터 인터페이스를 사용 IReadOnlyList<T>
하거나 ( ReadOnlyCollection
) 클래스를 래핑 하지 않도록 ( ) 사용할 수 있습니다 . 기본 어레이와 비슷한 성능을 제공합니다. blogs.msdn.microsoft.com/dotnet/2013/06/24/…
읽기 전용 마킹 사용의 또 다른 흥미로운 부분은 싱글 톤에서 필드가 초기화되지 않도록 보호하는 것입니다.
예를 들어 csharpindepth의 코드에서 :
public sealed class Singleton
{
private static readonly Lazy<Singleton> lazy =
new Lazy<Singleton>(() => new Singleton());
public static Singleton Instance { get { return lazy.Value; } }
private Singleton()
{
}
}
readonly는 Singleton 필드가 두 번 초기화되지 않도록 보호하는 작은 역할을합니다. 또 다른 세부 사항은 언급 된 시나리오의 경우 const가 컴파일 시간 동안 작성을 강제하기 때문에 const를 사용할 수는 없지만 싱글 톤은 런타임에 작성한다는 것입니다.
readonly
선언시 초기화되거나 생성자에서만 값을 얻을 수 있습니다. 달리 const
초기화하고 동시에 선언해야합니다.
readonly
모든 것이 const
있고 생성자 초기화
using System;
class MainClass {
public static void Main (string[] args) {
Console.WriteLine(new Test().c);
Console.WriteLine(new Test("Constructor").c);
Console.WriteLine(new Test().ChangeC()); //Error A readonly field
// `MainClass.Test.c' cannot be assigned to (except in a constructor or a
// variable initializer)
}
public class Test {
public readonly string c = "Hello World";
public Test() {
}
public Test(string val) {
c = val;
}
public string ChangeC() {
c = "Method";
return c ;
}
}
}