etc./StackOverFlow

'정적 읽기 전용' 대 'const'

청렴결백한 만능 재주꾼 2022. 3. 4. 07:55
반응형

질문자 :Svish


conststatic readonly 필드에 대해 읽었습니다. 상수 값만 포함하는 일부 클래스가 있습니다. 그것들은 우리 시스템의 다양한 것들에 사용됩니다. 그래서 내 관찰이 올바른지 궁금합니다.

이러한 종류의 상수 값은 공개된 모든 항목에 대해 static readonly 그리고 내부/보호/개인 값 const

추천 메뉴가 무엇인가요? static readonly 필드를 사용하지 않고 속성을 사용해야 합니까?



public static readonly 필드는 약간 특이합니다. public static 속성( get 만 포함)이 더 일반적입니다( private static readonly 필드에 의해 지원됨).

const 값은 호출 사이트에 직접 레코딩됩니다. 이것은 양날이다:

  • 값이 런타임에, 아마도 config에서 가져온다면 쓸모가 없습니다.
  • const 값을 변경하면 모든 클라이언트를 다시 빌드해야 합니다.
  • 그러나 메소드 호출을 피하기 때문에 더 빠를 수 있습니다 ...
  • ...어쨌든 때때로 JIT에 의해 인라인되었을 수 있습니다.

값이 변경되지 않으면 const는 괜찮습니다. - Zero 등은 합리적인 consts를 만듭니다. p 그 외에 static 속성이 더 일반적입니다.


Marc Gravell

소비자 가 다른 어셈블리에 있는 경우 static readonly 을 사용합니다. constConsumer 를 두 개의 다른 어셈블리에 두는 것은 발을 들여놓는 좋은 방법입니다.


Michael Stum

주의해야 할 몇 가지 추가 관련 사항:

상수 정수

  • 초기화해야 합니다.
  • 초기화는 컴파일 시간에 이루어져야 합니다.

읽기 전용 정수

  • 초기화하지 않고 기본값을 사용할 수 있습니다.
  • 초기화는 런타임에 수행될 수 있습니다(편집: 생성자 내에서만).

Peter

이것은 다른 답변에 대한 보충 자료일 뿐입니다. 나는 그것들을 반복하지 않을 것입니다(지금은 4년 후).

const 와 non-const가 다른 의미를 갖는 상황이 있습니다. 예를 들어:

 const int y = 42; static void Main() { short x = 42; Console.WriteLine(x.Equals(y)); }

True 출력하는 반면:

 static readonly int y = 42; static void Main() { short x = 42; Console.WriteLine(x.Equals(y)); }

False 씁니다.

그 이유는 x.Equals 메서드에 두 개의 오버로드가 short ( System.Int16 )를 사용하고 다른 하나는 object ( System.Object )를 사용합니다. 이제 문제는 하나 또는 둘 모두가 내 y 인수에 적용되는지 여부입니다.

경우 y (리터) 컴파일 시간 상수는 상기 const 경우, 그것으로부터 암시 적 변환이 존재하는 것이 중요해진다 int short 가 제공 int C # 컴파일러 검증하고 그 값 내에 있다는 것을 상수 제공된 short 범위( 42 ). C# 언어 사양에서 암시적 상수 식 변환 을 참조하세요. 따라서 두 과부하를 모두 고려해야 합니다. 오버로드 Equals(short) 가 선호됩니다(모든 shortobject 이지만 모든 objectshort 는 아닙니다). 따라서 y short 로 변환되고 해당 과부하가 사용됩니다. 그런 다음 Equals 는 동일한 값이 short 두 개를 비교 true 를 제공합니다.

y 가 상수가 아니면 int 에서 short 로의 암시적 변환이 존재하지 않습니다. int short 에 맞추기에는 너무 클 수 있기 때문입니다. ( 명시적인 변환이 존재하지만 Equals((short)y) 라고 말하지 않았으므로 관련이 없습니다. 우리는 Equals(object) 하나만 적용되는 오버로드를 봅니다. 따라서 y object boxing됩니다. 그런 다음 EqualsSystem.Int16System.Int32 와 비교하고 런타임 유형이 일치하지 않기 때문에 false 를 산출합니다.

일부(드문) 경우에 const 유형 멤버를 static readonly 필드로 변경하면(또는 가능한 경우 다른 방식으로) 프로그램의 동작이 변경될 수 있다고 결론지었습니다.


Jeppe Stig Nielsen

주의해야 할 한 가지는 const 가 기본/값 유형으로 제한된다는 것입니다(문자열은 예외).


Chris S

정적 읽기 전용 :

값은 런타임에 static 생성자를 통해 변경할 수 있습니다. 그러나 멤버 함수를 통해서는 아닙니다.

상수 :

기본적으로 static . 값은 어디에서나 변경할 수 없습니다(생성자, 함수, 런타임 등 아무데도 없음).

읽기 전용 :

값은 런타임에 생성자를 통해 변경할 수 있습니다. 그러나 멤버 함수를 통해서는 아닙니다.

내 리포지토리를 볼 수 있습니다. C# 속성 유형 .


Yeasin Abedin

readonly 키워드는 const 키워드와 다릅니다. const 필드는 필드 선언 시에만 초기화할 수 있습니다. readonly 필드는 선언이나 생성자에서 초기화할 수 있습니다. 따라서 readonly 필드는 사용되는 생성자에 따라 다른 값을 가질 수 있습니다. 또한 const 필드는 컴파일 타임 상수이지만 readonly 필드는 런타임 상수에 사용할 수 있습니다.

여기에서 짧고 명확한 MSDN 참조


yazanpro

constreadonly 는 비슷하지만 완전히 동일하지는 않습니다.

const 필드는 컴파일 타임 상수이며, 이는 해당 값이 컴파일 타임에 계산될 수 있음을 의미합니다. readonly 필드를 사용하면 형식을 구성하는 동안 일부 코드를 실행해야 하는 추가 시나리오를 사용할 수 있습니다. 생성 후에는 readonly 필드를 변경할 수 없습니다.

예를 들어, 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, green, blue) = (r, g, 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, green, blue) = (r, g, 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 개발자가 의도를 지정할 수 있습니다. 이것은 더 나은 버전 관리 동작과 더 나은 성능을 제공합니다.


Ramesh Rajendran

내가 선호하는 것은 이전 답변에서 언급했듯이 리터럴 표현식이나 평가가 필요하지 않은 것으로 제한되는 가능한 한 const를 사용하는 것입니다.

그 제한에 부딪히면 한 가지 주의 사항과 함께 static readonly 로 폴백합니다. 나는 일반적으로 Marc가 여기에서 언급한 것처럼 getter 및 지원하는 private static readonly 필드와 함께 public static 속성을 사용합니다.


Peter Meyer

정적 읽기 전용 필드는 이후 버전에서 변경될 수 있는 값을 다른 어셈블리에 노출할 때 유리합니다.

예를 들어 어셈블리 X 가 다음과 같이 상수를 노출한다고 가정합니다.

 public const decimal ProgramVersion = 2.3;

어셈블리 Y X 참조하고 이 상수를 사용하는 경우 값 2.3은 컴파일할 때 Y 경우에 것을이 수단 X 나중에 2.4로 일정하게 세트를 다시 컴파일, Y 아직까지 2.3의 이전 값을 사용합니다 Y 다시 컴파일됩니다. 정적 읽기 전용 필드는 이 문제를 방지합니다.

이를 보는 또 다른 방법은 미래에 변경될 수 있는 모든 값이 정의에 따라 일정하지 않으므로 하나로 표시되어서는 안 된다는 것입니다.


Yagnesh Cangi

Const: Const는 "상수"에 불과하며, 이 변수의 값은 일정하지만 컴파일 시간에는 변하지 않습니다. 그리고 그것에 값을 할당하는 것은 필수입니다. 기본적으로 const는 정적이며 전체 프로그램에서 const 변수의 값을 변경할 수 없습니다.

정적 읽기 전용: 정적 읽기 전용 유형 변수의 값은 런타임에 할당되거나 컴파일 시간에 할당되고 런타임에 변경될 수 있습니다. 그러나 이 변수의 값은 정적 생성자에서만 변경할 수 있습니다. 그리고 더 이상 변경할 수 없습니다. 런타임에 한 번만 변경할 수 있습니다.

참조: c-sharpcorner


mayank

Const : 상수 변수 값은 선언과 함께 정의되어야 하며 이후에는 변경되지 않습니다. const는 암시적으로 정적이므로 클래스 인스턴스를 만들지 않고도 액세스할 수 있습니다. 이것은 컴파일 타임에 값을 갖습니다.

ReadOnly : 런타임에 생성자를 사용할 뿐만 아니라 선언하는 동안 읽기 전용 변수 값을 정의할 수 있습니다. 읽기 전용 변수는 클래스 인스턴스 없이 액세스할 수 없습니다.

정적 읽기 전용 : 선언하는 동안 정적 읽기 전용 변수 값을 정의할 수 있을 뿐만 아니라 정적 생성자를 통해서만 정의할 수 있지만 다른 생성자는 사용할 수 없습니다. 클래스 인스턴스를 만들지 않고도 이러한 변수에 액세스할 수도 있습니다(정적 변수로).

다른 어셈블리에서 변수를 사용해야 하는 경우 정적 읽기 전용이 더 나은 선택입니다. 자세한 내용은 아래 블로그 게시물에서 확인하세요.

Const Strings – 발에 총을 쏘는 매우 편리한 방법


user1756922

C#.Net의 const 및 정적 읽기 전용 필드 사이에는 약간의 차이가 있습니다.

const는 컴파일 타임에 값으로 초기화되어야 합니다.

const는 기본적으로 정적이며 나중에 수정할 수 없는 상수 값으로 초기화해야 합니다. 모든 데이터 유형에 사용할 수는 없습니다. 전 DateTime의 경우. DateTime 데이터 유형과 함께 사용할 수 없습니다.

 public const DateTime dt = DateTime.Today; //throws compilation error public const string Name = string.Empty; //throws compilation error public static readonly string Name = string.Empty; //No error, legal

readonly는 정적으로 선언할 수 있지만 필수는 아닙니다. 선언 시 초기화할 필요가 없습니다. 해당 값은 생성자를 한 번만 사용하여 할당하거나 변경할 수 있습니다. 따라서 readonly 필드의 값을 한 번 변경할 가능성이 있습니다(정적이든 아니든 상관 없음). 이는 const에서는 불가능합니다.


Chirag

상수:

  1. 값은 선언 시 제공되어야 합니다.
  2. 컴파일 시간 상수

읽기 전용:

  1. 값은 선언 시 또는 런타임 중에 생성자를 사용하여 제공될 수 있습니다. 값은 사용된 생성자에 따라 다를 수 있습니다.
  2. 런타임 상수

dasumohan89

const(컴파일 타임에 결정됨)는 switch 문이나 속성 생성자와 같이 readonly static이 할 수 없는 경우에 사용할 수 있습니다. 이는 읽기 전용 필드가 런타임에만 확인되고 일부 코드 구성에는 컴파일 시간 보장이 필요하기 때문입니다. 읽기 전용 정적은 생성자에서 계산할 수 있으며, 이는 종종 필수적이고 유용한 것입니다. 차이점은 기능적이며 내 의견으로는 사용법이 필요합니다.

메모리 할당 측면에서 적어도 문자열(참조 유형)의 경우 둘 다 인턴되고 하나의 인턴 인스턴스를 참조한다는 점에서 차이가 없는 것 같습니다.

개인적으로 내 기본값은 읽기 전용 정적입니다. 특히 대부분의 값이 컴파일 타임에 필요하지 않기 때문에 더 의미론적이고 논리적으로 이해하기 쉽습니다. 그리고 그건 그렇고, 공개 읽기 전용 정적은 표시된 답변에서 알 수 있듯이 일반적이지 않거나 전혀 일반적이지 않습니다. 예를 들어 System.String.Empty 는 하나입니다.


DvS

const 선언과 정적 읽기 전용의 또 다른 차이점은 메모리 할당에 있습니다.

정적 필드는 해당 유형 의 인스턴스가 아니라 개체 유형에 속합니다. 결과적으로 클래스가 처음으로 참조되면 정적 필드는 나머지 시간 동안 메모리에 "살아있"고 정적 필드의 동일한 인스턴스는 해당 유형의 모든 인스턴스에서 참조됩니다.

반면에 const 필드는 "유형의 인스턴스에 속합니다.

할당 해제 메모리가 더 중요하다면 const 사용을 선호합니다. 속도가 빠르면 static readonly 를 사용하십시오.


Boris Lipschitz

상수는 이름에서 알 수 있듯이 변경되지 않고 일반적으로 코드에서 컴파일 타임에 정적으로 정의되는 필드입니다.

읽기 전용 변수는 특정 조건에서 변경될 수 있는 필드입니다.

상수처럼 처음 선언할 때 초기화할 수 있지만 일반적으로 생성자 내부에서 객체를 생성하는 동안 초기화됩니다.

위에서 언급한 조건에서 초기화가 발생한 후에는 변경할 수 없습니다.

정적 읽기 전용은 정적이고 변경되지 않는 경우 나에게 좋지 않은 선택처럼 들릴 수 있으므로 public const를 사용하십시오. 변경될 수 있는 경우 상수가 아니며 필요에 따라 읽기 전용 또는 일반 변수만 사용할 수 있습니다.

또한 또 다른 중요한 차이점은 상수는 클래스에 속하고 읽기 전용 변수는 인스턴스에 속한다는 것입니다!


Claudiu Cojocaru

위의 답변 어디에도 언급되지 않은 한 가지 중요한 질문이 있으며 특히 "int", "string" 등과 같은 기본 유형에 대해 "const"를 선호하도록 유도해야 합니다.

상수는 속성 매개변수로 사용할 수 있으며 정적 읽기 전용 필드는 사용할 수 없습니다!

Azure 함수 HttpTrigger, 특성에서 HttpMethods 클래스를 사용하지 않음

Microsoft만 Http의 GET, POST, DELETE 등에 상수를 사용한 경우

쓰는 것이 가능했을 것이다.

 [HttpTrigger(AuthorizationLeve.Anonymous, HttpMethods.Get)] // COMPILE ERROR: static readonly,

그러나 대신에 나는 의지해야합니다.

 [HttpTrigger(AuthorizationLeve.Anonymous, "GET")] // STRING

또는 내 자신의 상수를 사용하십시오.

 public class HttpConstants { public const string Get = "GET"; } [HttpTrigger(AuthorizationLeve.Anonymous, HttpConstants.Get)] // Compile FINE!

UberFace

컴파일 타임 상수를 제공할 수 있는 경우 const 사용합니다.

 private const int Total = 5;

런타임 중에 값을 평가해야 하는 경우 static readonly 사용합니다.

 private static readonly int GripKey = Animator.StringToHash("Grip");

컴파일 타임에 값을 가져올 수 없기 때문에 컴파일 오류가 발생합니다.

 private const int GripKey = Animator.StringToHash("Grip");

Guney Ozsan

출처 : http:www.stackoverflow.com/questions/755685/static-readonly-vs-const

반응형