이에 대해 동료와 우호적 인 토론을합니다. 우리는 이것에 대해 약간의 생각을 가지고 있지만 SO 군중이 이것에 대해 어떻게 생각하는지 궁금하십니까?
이에 대해 동료와 우호적 인 토론을합니다. 우리는 이것에 대해 약간의 생각을 가지고 있지만 SO 군중이 이것에 대해 어떻게 생각하는지 궁금하십니까?
답변:
한 가지 이유는 읽기 전용 로컬에 대한 CLR 지원이 없기 때문입니다. 읽기 전용은 CLR / CLI initonly opcode로 변환됩니다. 이 플래그는 필드에만 적용 할 수 있으며 로컬에는 의미가 없습니다. 실제로 로컬에 적용하면 확인할 수없는 코드가 생성 될 수 있습니다.
이것은 C #이 이것을 할 수 없다는 것을 의미하지 않습니다. 그러나 동일한 언어 구조에 두 가지 다른 의미를 부여합니다. 로컬 버전에는 CLR에 해당하는 매핑이 없습니다.
readonly
필드 의 키워드는 그 효과 가 다른 어셈블리에 표시 되므로 CLI에서 지원해야합니다 . 그것이 의미하는 것은 변수가 컴파일 타임에 메서드에 하나의 할당 만 있다는 것입니다.
const
(C ++에서는 두 역할을 모두 수행 할 수 있지만 C # readonly
보다 C #과 비슷 const
합니다). 그러나 C ++는 const
지역 자동 변수를 지원 합니다. 따라서 readonly
지역 변수에 대한 C #에 대한 CLR 지원의 부족 은 관련이 없습니다.
using
하고 out
정확하고 있음을하며 세계는 붕괴하지 않았다.
나는 C # 아키텍트의 일부에 대한 잘못된 판단이라고 생각합니다. 지역 변수에 대한 readonly 한정자는 프로그램 정확성을 유지하는 데 도움이되고 (어설 션과 마찬가지로) 컴파일러가 코드를 최적화하는 데 도움이 될 수 있습니다 (적어도 다른 언어의 경우). 현재 C #에서 허용되지 않는다는 사실은 C #의 "기능"중 일부가 제작자의 개인 코딩 스타일을 적용한 것일 뿐이라는 또 다른 주장입니다.
Jared의 대답을 처리하면 아마도 컴파일 타임 기능이어야 할 것입니다. 컴파일러는 초기 선언 (할당을 포함해야 함) 후에 변수에 쓰는 것을 금지합니다.
이것에서 가치를 볼 수 있습니까? 잠재적으로-솔직히 많이는 아닙니다. 변수가 메서드의 다른 위치에 할당 될지 여부를 쉽게 알 수 없다면 메서드가 너무 깁니다.
무엇의 가치를 들면, 자바합니다 (사용하여이 기능이 final
수정을) 내가 한 매우 드물게 그것 경우 이외의 사용 본적 이 변수가 익명의 내부 클래스에 의해 포착 할 수 있도록 사용하는 - 그것은 어디에 이다 사용하면 유용한 정보가 아니라 어수선한 느낌을줍니다.
readonly
/ final
값을 변수와 구별 합니다. Scala 코드에서 local 은 매우 자주 사용 됩니다 (실제로 local s 보다 선호 됨 ). 수정자가 Java에서 더 자주 사용되지 않는 주된 이유 는 a) 혼란스럽고 b) 게으름 때문이라고 생각합니다. val
var
val
var
final
readonly
경우 지나치게 중요하지 않습니다. 반면에 클로저에 사용되는 지역 변수의 readonly
경우 많은 경우 컴파일러가 더 효율적인 코드를 생성 할 수 있습니다. 현재, 클로저가 포함 된 블록에 실행이 시작되면 컴파일러는 클로저를 사용하는 코드가 실행되지 않더라도 닫힌 변수에 대한 새 힙 객체를 만들어야합니다 . 변수가 읽기 전용이면 클로저 외부의 코드는 일반 변수를 사용할 수 있습니다. 클로저를 위해 델리게이트가 생성 된 경우에만 ...
제안 읽기 전용 지역 및 매개 변수에 대한은 C # 7 디자인 팀에서 간략하게 논의했습니다. 에서 2015년 1월 21일에 대한 C # 디자인 회의 노트 :
매개 변수와 로컬은 람다로 캡처하여 동시에 액세스 할 수 있지만 공유 상호 상태 문제로부터 보호 할 수있는 방법은 없습니다. 읽기 전용 일 수 없습니다.
일반적으로 대부분의 매개 변수와 많은 로컬은 초기 값을 얻은 후에는 할당되지 않습니다. 그들에게 읽기 전용을 허용하면 그 의도를 명확하게 표현할 수 있습니다.
한 가지 문제는이 기능이 "매력적인 골칫거리"일 수 있다는 것입니다. "올바른 일"은 거의 항상 매개 변수와 지역을 읽기 전용으로 만드는 것이지만 그렇게하려면 코드가 상당히 복잡해집니다.
이를 부분적으로 완화하는 아이디어는 지역 변수의 readonly var 조합을 val 또는 이와 유사한 짧은 값으로 축소하는 것입니다. 더 일반적으로 우리는 읽기 전용을 표현하기 위해 설정된 읽기 전용보다 짧은 키워드를 생각할 수 있습니다.
토론은 C # 언어 디자인 리포지토리에서 계속됩니다. 지지를 보여주기 위해 투표하십시오. https://github.com/dotnet/csharplang/issues/188
읽기 전용은 인스턴스 변수를 설정할 수있는 유일한 위치가 생성자에 있음을 의미합니다. 변수를 로컬로 선언 할 때 인스턴스가 없으며 (범위 내에 있음) 생성자가 건드릴 수 없습니다.
나는 이것이 당신의 질문에 대한 이유에 대한 답이 아닙니다. 어쨌든이 질문을 읽는 사람들은 그럼에도 불구하고 아래 코드를 고맙게 생각할 것입니다.
한 번만 설정해야하는 로컬 변수를 재정의 할 때 자신의 발에 자신을 쏘는 데 정말로 관심이 있고 더 전역 적으로 액세스 가능한 변수로 만들고 싶지 않은 경우 다음과 같이 할 수 있습니다.
public class ReadOnly<T>
{
public T Value { get; private set; }
public ReadOnly(T pValue)
{
Value = pValue;
}
public static bool operator ==(ReadOnly<T> pReadOnlyT, T pT)
{
if (object.ReferenceEquals(pReadOnlyT, null))
{
return object.ReferenceEquals(pT, null);
}
return (pReadOnlyT.Value.Equals(pT));
}
public static bool operator !=(ReadOnly<T> pReadOnlyT, T pT)
{
return !(pReadOnlyT == pT);
}
}
사용 예 :
var rInt = new ReadOnly<int>(5);
if (rInt == 5)
{
//Int is 5 indeed
}
var copyValueOfInt = rInt.Value;
//rInt.Value = 6; //Doesn't compile, setter is private
코드만큼 rvar rInt = 5
적지 는 않지만 작동합니다.
C # 대화 형 컴파일러를 사용하는 경우 C #에서 읽기 전용 지역 변수를 선언 할 수 있습니다 csi
.
>"C:\Program Files (x86)\MSBuild\14.0\Bin\csi.exe"
Microsoft (R) Visual C# Interactive Compiler version 1.3.1.60616
Copyright (C) Microsoft Corporation. All rights reserved.
Type "#help" for more information.
> readonly var message = "hello";
> message = "goodbye";
(1,1): error CS0191: A readonly field cannot be assigned to (except in a constructor or a variable initializer)
.csx
스크립트 형식으로 읽기 전용 지역 변수를 선언 할 수도 있습니다 .
message
여기서는 변수가 아니며 필드로 컴파일됩니다. 대화 형 C #에서도 구별이 명확하게 존재하기 때문에 이것은 간단하지 않습니다.int x; Console.WriteLine(x)
합법적 인 대화 형 C # ( x
필드이고 암시 적으로 초기화 void foo() { int x; Console.WriteLine(x); }
되었기 때문 )이지만 그렇지 않습니다 ( x
변수이고 할당되기 전에 사용되기 때문입니다). 또한 이것이 실제로 지역 변수가 아닌 필드 Expression<Func<int>> y = x; ((MemberExpression) y.Body).Member.MemberType
임을 나타냅니다 x
.
C #에는 약간 다른 구문이지만 이미 읽기 전용 var가 있습니다.
다음 줄을 고려하십시오.
var mutable = myImmutableCalculationMethod();
readonly var immutable = mutable; // not allowed in C# 8 and prior versions
return immutable;
비교 :
var mutable = myImmutableCalculationMethod();
string immutable() => mutable; // allowed in C# 7
return immutable();
첫 번째 해결책은 작성해야 할 코드가 적을 수 있습니다. 그러나 두 번째 스 니펫은 변수를 참조 할 때 읽기 전용을 명시 적으로 만듭니다.
readonly var im = new List<string>(); im.Add("read-only variable, mutable object!");
.
사용하다 const
읽기 전용 변수를 만들려면 키워드를 하십시오.
참조 : https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/const
public class SealedTest
{
static void Main()
{
const int c = 707;
Console.WriteLine("My local constant = {0}", c);
}
}
const
변수가 초기화 동안에 만 할당 될 수 있는 JavaScript 스타일에 관심 const
이 있습니다. 컴파일 타임 표현식 만 사용할 수있는 csharp 스타일 이 아닙니다. 예를 들어, 당신은 할 수 const object c = new object();
있지만, readonly
지역은 당신이 할 수있는 것입니다.