C#에서 const
와 readonly
의 차이점은 무엇입니까?
언제 다른 것보다 하나를 사용하시겠습니까?
질문자 :readonly
C#에서 const
와 readonly
의 차이점은 무엇입니까?
언제 다른 것보다 하나를 사용하시겠습니까?
겉으로 보이는 차이 외에
const
VS readonly
값을 정의할 때 값을 선언해야 하는 것은 동적으로 계산할 수 있지만 생성자가 종료되기 전에 할당해야 합니다. 그 후에는 고정됩니다.const
는 암시적으로 static
입니다. ClassName.ConstantName
표기법을 사용하여 액세스합니다. 미묘한 차이가 있습니다. AssemblyA
정의된 클래스를 고려하십시오.
public class Const_V_Readonly { public const int I_CONST_VALUE = 2; public readonly int I_RO_VALUE; public Const_V_Readonly() { I_RO_VALUE = 3; } }
AssemblyB
참조 AssemblyA
코드에서이 값을 사용합니다. 이것이 컴파일되면:
const
값의 경우 찾기-바꾸기와 같습니다. 값 2는 AssemblyB
의 IL에 '구입'됩니다. 즉, 내일 I_CONST_VALUE
를 20으로 AssemblyB
는 다시 컴파일할 때까지 여전히 2를 갖게 됩니다 .readonly
값의 경우 메모리 위치에 ref
와 같습니다. AssemblyB
의 IL에 구워지지 않습니다. 즉, 메모리 위치가 업데이트되면 AssemblyB
가 다시 컴파일하지 않고 새 값을 가져옵니다. 따라서 I_RO_VALUE
가 30으로 업데이트 AssemblyA
만 빌드하면 되고 모든 클라이언트는 다시 컴파일할 필요가 없습니다. 따라서 상수 값이 변경되지 않을 것이라고 확신한다면 const
사용하십시오.
public const int CM_IN_A_METER = 100;
그러나 변경될 수 있는 상수가 있는 경우(egwrt 정밀도).. 의심스러운 readonly
사용하십시오.
public readonly float PI = 3.14;
업데이트: Aku가 먼저 이것을 지적했기 때문에 언급을 받아야 합니다. 또한 나는 이것을 배운 곳에 연결해야 합니다: Effective C# - Bill Wagner
const가 있는 문제가 있습니다! 다른 어셈블리에서 상수를 참조하는 경우 해당 값은 호출 어셈블리로 바로 컴파일됩니다. 그렇게하면 참조 된 어셈블리에서 상수를 업데이트 할 때 호출 어셈블리에서 변경되지 않습니다!
다만, 추가 readonly
단지뿐만 아니라 값을 읽을 참조를 만드는 참조 유형. 예를 들어:
public class Const_V_Readonly { public const int I_CONST_VALUE = 2; public readonly char[] I_RO_VALUE = new Char[]{'a', 'b', 'c'}; public UpdateReadonly() { I_RO_VALUE[0] = 'V'; //perfectly legal and will update the value I_RO_VALUE = new char[]{'V'}; //will cause compiler error } }
이것 은 그것을 설명 합니다 . 요약: const는 선언 시 초기화되어야 하고 readonly는 생성자에서 초기화될 수 있습니다(따라서 사용된 생성자에 따라 다른 값을 가짐).
편집: 미묘한 차이는 위의 Gishu's gotcha를 참조하십시오.
const
: 어디에서나 변경할 수 없습니다.
readonly
: 이 값은 생성자에서만 변경할 수 있습니다. 일반 기능에서는 변경할 수 없습니다.
상수 멤버는 컴파일 시 정의되며 런타임 시 변경할 수 없습니다. const
키워드를 사용하여 필드로 선언되며 선언된 대로 초기화되어야 합니다.
public class MyClass { public const double PI1 = 3.14159; }
readonly
멤버는 변하지 않는 값을 나타낸다는 점에서 상수와 같습니다. 차이점은 readonly
멤버는 런타임에 생성자에서 초기화될 수 있을 뿐만 아니라 선언된 대로 초기화될 수 있다는 것입니다.
public class MyClass1 { public readonly double PI2 = 3.14159; //or public readonly double PI3; public MyClass2() { PI3 = 3.14159; } }
상수
static
으로 선언할 수 없습니다(암시적으로 정적임).읽기 전용
읽기 전용이 있는 작은 문제가 있습니다. 읽기 전용 필드는 생성자 내에서 여러 번 설정할 수 있습니다. 값이 두 개의 서로 다른 연결 생성자에 설정되어 있어도 여전히 허용됩니다.
public class Sample { private readonly string ro; public Sample() { ro = "set"; } public Sample(string value) : this() { ro = value; // this works even though it was set in the no-arg ctor } }
const는 컴파일 타임 상수인 반면 readonly를 사용하면 런타임에 값을 계산하고 생성자 또는 필드 이니셜라이저에서 설정할 수 있습니다. 따라서 'const'는 항상 일정하지만 'readonly'는 일단 할당되면 읽기 전용입니다.
C# 팀의 Eric Lippert는 다양한 유형의 불변성에 대한 자세한 정보를 제공합니다.
다음은 const가 버전 안전하지 않거나 참조 유형과 관련이 없는 방법을 보여주는 또 다른 링크입니다.
요약 :
읽기 전용 : 런타임 시 Ctor를 통해 값을 변경할 수 있습니다. 하지만 멤버 함수를 통해서가 아닙니다.
상수 : 기본적으로 정적입니다. 값은 어디에서나 변경할 수 없습니다(Ctor, Function, 런타임 등 없음).
또 다른 문제: 읽기 전용 값은 리플렉션을 통해 "비뚤어진" 코드로 변경할 수 있습니다.
var fi = this.GetType() .BaseType .GetField("_someField", BindingFlags.Instance | BindingFlags.NonPublic); fi.SetValue(this, 1);
const
값이 모든 객체에 대해 동일하다고 생각하지만(리터럴 표현식으로 초기화해야 함), readonly
는 각 인스턴스화에 대해 다를 수 있습니다...
둘 다 일정하지만 const는 컴파일 타임에도 사용할 수 있습니다. 즉, 차이점의 한 측면은 const 변수를 속성 생성자에 대한 입력으로 사용할 수 있지만 읽기 전용 변수는 사용할 수 없다는 것입니다.
예시:
public static class Text { public const string ConstDescription = "This can be used."; public readonly static string ReadonlyDescription = "Cannot be used."; } public class Foo { [Description(Text.ConstDescription)] public int BarThatBuilds { { get; set; } } [Description(Text.ReadOnlyDescription)] public int BarThatDoesNotBuild { { get; set; } } }
우리 사무실의 팀원 중 한 명이 const, static 및 readonly를 언제 사용해야 하는지에 대해 다음 지침을 제공했습니다.
마지막 참고 사항: const 필드는 정적이지만 그 반대는 사실이 아닙니다.
const
또는 readonly
를 사용할 때
const
readonly
App.config
통해 생성자/초기화에서 설정할 수 있지만 일단 초기화되면 변경할 수 없습니다.const로 표시된 변수는 강력한 형식의 #define 매크로에 불과하며 컴파일 시간에 const 변수 참조가 인라인 리터럴 값으로 대체됩니다. 결과적으로 특정 기본 제공 기본 값 유형만 이러한 방식으로 사용할 수 있습니다. 읽기 전용으로 표시된 변수는 런타임 시 생성자에서 설정할 수 있으며 해당 읽기 전용성은 런타임 중에도 적용됩니다. 이와 관련된 약간의 성능 비용이 있지만 이는 모든 유형(참조 유형 포함)에서 읽기 전용으로 사용할 수 있음을 의미합니다.
또한 const 변수는 본질적으로 정적이지만 읽기 전용 변수는 원하는 경우 인스턴스에 따라 다를 수 있습니다.
C#.Net에서 const와 readonly 필드 사이에는 눈에 띄는 차이점이 있습니다.
const는 기본적으로 정적이며 나중에 수정할 수 없는 상수 값으로 초기화해야 합니다. 생성자에서도 값 변경이 허용되지 않습니다. 모든 데이터 유형에 사용할 수는 없습니다. 전 DateTime의 경우. DateTime 데이터 유형과 함께 사용할 수 없습니다.
public const DateTime dt = DateTime.Today; //throws compilation error public const string Name = string.Empty; //throws compilation error public readonly string Name = string.Empty; //No error, legal
readonly는 정적으로 선언할 수 있지만 필수는 아닙니다. 선언 시 초기화할 필요가 없습니다. 생성자를 사용하여 값을 할당하거나 변경할 수 있습니다. 따라서 인스턴스 클래스 멤버로 사용할 때 이점이 있습니다. 두 개의 다른 인스턴스화는 읽기 전용 필드의 값이 다를 수 있습니다. 예를 들어 -
class A { public readonly int Id; public A(int i) { Id = i; } }
그런 다음 읽기 전용 필드는 다음과 같이 즉각적인 특정 값으로 초기화될 수 있습니다.
A objOne = new A(5); A objTwo = new A(10);
여기에서 인스턴스 objOne은 readonly 필드 값이 5이고 objTwo는 10입니다. 이는 const를 사용하여 불가능합니다.
또 다른 문제 .
const는 실제로 기본 데이터 유형에서만 작동하기 때문에 클래스로 작업하려는 경우 ReadOnly를 "강제로" 사용해야 한다고 느낄 수 있습니다. 그러나 함정을 조심하십시오! ReadOnly는 개체를 다른 개체로 바꿀 수 없음을 의미합니다(다른 개체를 참조하게 할 수 없음). 그러나 객체에 대한 참조가 있는 모든 프로세스는 객체 내부 의 값을 자유롭게 수정할 수 있습니다!
따라서 ReadOnly가 사용자가 변경할 수 없다는 것을 의미한다고 혼동하지 마십시오. C#에는 클래스의 인스턴스화에서 내부 값이 변경되는 것을 방지하는 간단한 구문이 없습니다(내가 아는 한).
const
는 하드 코딩 되어야 하며, readonly
는 클래스 생성자에서 설정할 수 있습니다.
상수는 리터럴 값으로 소비자에 컴파일되는 반면 정적 문자열은 정의된 값에 대한 참조 역할을 합니다.
연습으로 외부 라이브러리를 만들어 콘솔 응용 프로그램에서 사용한 다음 라이브러리의 값을 변경하고 다시 컴파일하고(소비자 프로그램을 다시 컴파일하지 않고) DLL을 디렉터리에 넣고 EXE를 수동으로 실행하면 다음을 찾아야 합니다. 상수 문자열은 변경되지 않습니다.
Const와 readonly는 비슷하지만 완전히 동일하지는 않습니다. const 필드는 컴파일 타임 상수이며, 이는 해당 값이 컴파일 타임에 계산될 수 있음을 의미합니다. 읽기 전용 필드를 사용하면 형식을 구성하는 동안 일부 코드를 실행해야 하는 추가 시나리오를 사용할 수 있습니다. 생성 후에는 읽기 전용 필드를 변경할 수 없습니다.
예를 들어, const 멤버는 다음과 같은 멤버를 정의하는 데 사용할 수 있습니다.
struct Test { public const double Pi = 3.14; public const int Zero = 0; }
3.14 및 0과 같은 값은 컴파일 타임 상수이기 때문입니다. 그러나 유형을 정의하고 해당 유형의 일부 조립식 인스턴스를 제공하려는 경우를 고려하십시오. 예를 들어, Color 클래스를 정의하고 Black, White 등과 같은 일반적인 색상에 대해 "상수"를 제공하고 싶을 수 있습니다. 오른쪽이 컴파일 타임 상수가 아니기 때문에 const 멤버로 이 작업을 수행할 수 없습니다. 일반 정적 멤버로 이 작업을 수행할 수 있습니다.
public class Color { public static Color Black = new Color(0, 0, 0); public static Color White = new Color(255, 255, 255); public static Color Red = new Color(255, 0, 0); public static Color Green = new Color(0, 255, 0); public static Color Blue = new Color(0, 0, 255); private byte red, green, blue; public Color(byte r, byte g, byte b) { red = r; green = g; blue = b; } }
그러나 Color의 클라이언트가 Black과 White 값을 교환하여 문제를 일으키는 것을 막을 방법은 없습니다. 말할 필요도 없이 이것은 Color 클래스의 다른 클라이언트를 당황하게 할 것입니다. "읽기 전용" 기능은 이 시나리오를 해결합니다. 선언에 readonly 키워드를 도입함으로써 유연한 초기화를 유지하면서 클라이언트 코드가 엉망이 되는 것을 방지할 수 있습니다.
public class Color { public static readonly Color Black = new Color(0, 0, 0); public static readonly Color White = new Color(255, 255, 255); public static readonly Color Red = new Color(255, 0, 0); public static readonly Color Green = new Color(0, 255, 0); public static readonly Color Blue = new Color(0, 0, 255); private byte red, green, blue; public Color(byte r, byte g, byte b) { red = r; green = g; blue = b; } }
const 멤버는 항상 정적이지만 readonly 멤버는 일반 필드와 마찬가지로 정적이거나 그렇지 않을 수 있습니다.
이 두 가지 목적을 위해 단일 키워드를 사용할 수 있지만 이는 버전 문제나 성능 문제로 이어집니다. 우리가 이것(const)에 대해 단일 키워드를 사용했고 개발자가 다음과 같이 썼다고 잠시 가정합니다.
public class A { public static const C = 0; }
다른 개발자는 A에 의존하는 코드를 작성했습니다.
public class B { static void Main() { Console.WriteLine(AC); } }
이제 생성된 코드가 AC가 컴파일 타임 상수라는 사실에 의존할 수 있습니까? 즉, AC 사용을 단순히 값 0으로 대체할 수 있습니까? 이에 대해 "예"라고 말하면 A 개발자가 AC가 초기화되는 방식을 변경할 수 없음을 의미합니다. 이는 A 개발자의 손을 무단으로 묶는 것입니다. 이 질문에 "아니오"라고 말하면 중요한 최적화를 놓친 것입니다. 아마도 A의 저자는 AC가 항상 0일 것이라고 긍정적입니다. const와 readonly를 모두 사용하면 A 개발자가 의도를 지정할 수 있습니다. 이것은 더 나은 버전 관리 동작과 더 나은 성능을 제공합니다.
ReadOnly : 값은 클래스의 생성자에서 한 번만 초기화됩니다.
const: 모든 함수에서 초기화할 수 있지만 한 번만
차이점은 정적 읽기 전용 필드의 값이 런타임에 설정되므로 프로그램 실행에 따라 다른 값을 가질 수 있다는 것입니다. 그러나 const 필드의 값은 컴파일 시간 상수로 설정됩니다.
기억하십시오: 참조 유형의 경우 두 경우 모두(정적 및 인스턴스) readonly 한정자는 필드에 새 참조를 할당하지 못하도록 막습니다. 특히 참조가 가리키는 객체를 불변으로 만들지 않습니다.
자세한 내용은 이 주제에 대한 C# 자주 묻는 질문을 참조하십시오. http://blogs.msdn.com/csharpfaq/archive/2004/12/03/274791.aspx
상수 변수는 컴파일 타임에 선언되고 초기화됩니다. 와드 이후에는 값을 변경할 수 없습니다. 읽기 전용 변수는 클래스의 정적 생성자에서만 초기화됩니다. 읽기 전용은 런타임에 값을 할당하려는 경우에만 사용됩니다.
주로; 정적 읽기 전용 필드에 값을 런타임에 상수가 아닌 값에 할당할 수 있는 반면 const에는 상수 값을 할당해야 합니다.
사람들이 위에서 말한 것에 한 가지를 추가합니다. 읽기 전용 값(예: readonly MaxFooCount = 4; )을 포함하는 어셈블리가 있는 경우 해당 어셈블리의 새 버전을 다른 값으로 배송하여 호출 어셈블리가 보는 값을 변경할 수 있습니다(예: readonly MaxFooCount = 5;).
그러나 const를 사용하면 호출자가 컴파일될 때 호출자의 코드로 접힐 것입니다.
이 수준의 C# 능숙도에 도달했다면 Bill Wagner의 책 Effective C#: 50 Specific Ways to Improve Your C#을 읽을 준비가 된 것입니다. 이 책에서는 이 질문에 대해 자세히 답변하고 있습니다.
주요 차이점은 Const가 #DEFINE에 해당하는 C라는 것입니다. 숫자는 말 그대로 사전 컴파일러로 대체됩니다. 읽기 전용은 실제로 변수로 취급됩니다.
이 구분은 프로젝트 B의 Public 상수에 따라 Project A가 있는 경우 특히 관련이 있습니다. public 상수가 변경된다고 가정합니다. 이제 const/readonly 선택이 프로젝트 A의 동작에 영향을 줍니다.
Const: 프로젝트 A는 대체된 상수로 컴파일되었기 때문에 새 값을 포착하지 않습니다(물론 새 const로 다시 컴파일하지 않는 한).
읽기 전용: 프로젝트 A는 항상 프로젝트 B에 변수 값을 요청하므로 B에서 공개 상수의 새 값을 선택합니다.
솔직히 말해서, 진정한 보편적 상수(예: Pi, Inches_To_Centimeters)를 제외한 거의 모든 것에 대해 읽기 전용을 사용하는 것이 좋습니다. 변경될 수 있는 모든 것에 대해서는 readonly를 사용한다고 말합니다.
도움이 되기를 바랍니다, 앨런.
Const : 애플리케이션 수명 동안 절대 상수 값입니다.
읽기 전용 : 실행 시간에 변경할 수 있습니다.
출처 : http:www.stackoverflow.com/questions/55984/what-is-the-difference-between-const-and-readonly-in-c
바이트 배열을 16진수 문자열로 또는 그 반대로 어떻게 변환합니까? (0) | 2022.02.27 |
---|---|
Docker 컨테이너의 셸에 어떻게 들어가나요? (0) | 2022.02.27 |
32비트 루프 카운터를 64비트로 교체하면 Intel CPU에서 _mm_popcnt_u64로 미친 성능 편차가 발생합니다. (0) | 2022.02.27 |
고방사성 환경에서 사용하기 위한 애플리케이션 컴파일 (0) | 2022.02.27 |
두 목록을 사전으로 어떻게 변환합니까? (0) | 2022.02.24 |