내 프로그램에서 사용하는 상수 그룹을 저장하는 가장 좋은 방법은 무엇입니까? [닫은]


97

내 프로그램에서 사용하는 다양한 상수가 있습니다 ... string's, int's, double's 등 ... 그것들을 저장하는 가장 좋은 방법은 무엇입니까? Enum데이터가 모두 동일한 유형이 아니므로 각 값을 수동으로 설정하고 싶기 때문에을 원하지 않는다고 생각 합니다. 모두 빈 클래스에 저장해야합니까? 아니면 더 좋은 방법이 있습니까?


18
당신이 그것을 원하는 방식-그것이 당신이 그것을 필요로하는 방식입니다.
San Jacinto

답변:


135

정적 읽기 전용 속성이있는 정적 클래스에있을 수 있습니다.

public static class Routes
{
    public static string SignUp => "signup";
}

23
+1하지만 현지화를 위해 리소스 파일에서 가져올 수 있다면 더 좋습니다.
Joel Coehoorn

17
약간 장황한 것 같습니다-정적 읽기 전용 문자열이 아닌 이유는 무엇입니까?
emptyset 2009

6
왜 읽기 전용이고 const가 아닌가? 런타임에 값을 설정하지 않으므로 읽기 전용으로 설정할 필요가 없습니다.
Philip Wallace

91
const의 문제는 const에 대해 컴파일 된 어셈블리가 자체적으로 컴파일 될 때 해당 const의 로컬 복사본을 얻는다는 것입니다. 따라서 값을 변경하는 경우 상수를 정의하는 어셈블리에 종속 된 모든 어셈블리도 다시 컴파일해야합니다. 따라서 읽기 전용 경로로 이동하는 것이 더 안전합니다. 공용 정적 값 대신 속성을 사용하면 인터페이스를 상수 값으로 변경하지 않고 필요할 경우 (예 : 현지화에서 읽기) 나중에 프로그래밍 논리를 추가 할 수있는 유연성을 제공합니다.
cfeduke

11
악마의 옹호자로서 저는 const의 장점은 스위치 케이스에서 사용할 수 있다는 점을 지적해야합니다.
arviman

27

상수로 가득 찬 클래스를 사용하는 IMO는 상수에 적합합니다. 가끔씩 변경되는 경우 구성에서 AppSettings를 사용하고 대신 ConfigurationManager 클래스를 사용하는 것이 좋습니다.

실제로 AppSettings 또는 이와 유사한 것에서 가져온 "상수"가있을 때 구성 관리자의 읽기를 래핑하는 "상수"클래스가 항상 있습니다. 상기 설정 값을 소비하고자하는 장소에 Constants.SomeModule.Setting직접 의지하지 않고 갖는 것이 항상 더 의미가 있습니다 ConfigurationManager.AppSettings["SomeModule/Setting"].

이 설정에 대한 보너스 포인트 SomeModule는 상수 파일 내부에 중첩 된 클래스 일 가능성이 높 SomeModule으므로 종속성 주입을 사용하여 종속 된 클래스에 직접 삽입 할 수 있습니다 . 또한 인터페이스를 추출한 SomeModule다음 ISomeModuleConfiguration소비 코드에 대한 종속성을 생성 할 수도 있습니다. 그러면 상수 파일에 대한 종속성을 분리 할 수 ​​있으며, 특히 이러한 설정이 AppSettings 및 설정은 환경에 따라 다르기 때문에 구성 변환을 사용하여 변경합니다.


1
추가하기 만하면됩니다. 그 이유는 빌드 할 때 다른 어셈블리에서 사용되는 상수가 업데이트되지 않기 때문입니다. 즉, AssemblyA와 AssemblyB가 있고 B가 A의 상수를 사용하는 경우 값이 참조되지 않고 복사되므로 A를 다시 빌드해도 B가 업데이트되지 않습니다. 이로 인해 이상한 버그가 발생할 수 있습니다.
Camilo Martin

1
@CamiloMartin 많은 방법으로이를 처리 할 수 ​​있습니다. "상수"는이를 방지하기 위해 정적 읽기 전용 일 수 있습니다. 또는 내가 말했듯이 구성 관리자를 사용하기 위해 블루 문에서 두 번 이상 변경하면됩니다.
Chris Marisic 2012 년

예, 정적 인 읽기 전용을 사용해야하는 관습 때문이 아니라 실제로 혼동의 원인이 될 수 있기 때문입니다. 또한 ConfigurationManager의 대안은 리소스 파일입니다. 이름에 언어 코드가 포함 된 다른 리소스 파일을 추가하기 만하면 코드가 즉시 현지화됩니다.
Camilo Martin

문제는 다른 어셈블리에서이 어셈블리를 참조 할 때 해당 구성 파일에 값을 복사해야한다는 것입니다
symbiont

당신은 설정 파일을 포함 할 수 @symbiont 당신이 제 3 자 구성 요소로 sharability를 들어, 원하는 경우 대신 매니페스트를 읽을
크리스 Marisic

19

내가 좋아하는 것은 다음과 같습니다 (그러나 올바른 유형의 상수 를 사용하려면 끝까지 읽으십시오 ).

internal static class ColumnKeys
{
    internal const string Date = "Date";
    internal const string Value = "Value";
    ...
}

const당신이 원하는 것이 아닐 수 있는지 알아 보려면 이것을 읽으십시오 . 가능한 상수 유형은 다음 과 같습니다.

  • const필드. 값이 다른 어셈블리에서 컴파일 타임에 하드 코딩되므로 나중에 값 변경 수있는 경우 어셈블리 ( public또는 protected)에서 사용하지 마십시오 . 값을 변경하면 다시 컴파일 될 때까지 다른 어셈블리에서 이전 값을 사용합니다.
  • static readonly 필드
  • static 없는 재산 set

1
여러 어셈블리에서 사용되는 경우 왜 읽기 전용입니까?
Philip Wallace

정적 읽기 전용이 const보다 여러 어셈블리에서 더 잘 작동하는 이유는 무엇입니까?
Matthew

15
Const 값은 소스 어셈블리에서 컴파일 된 코드로 복사됩니다. 즉, const 값을 변경해야하는 경우 모든 종속 어셈블리를 새 버전에 대해 다시 컴파일해야합니다. 정적 읽기 전용을 사용하는 것이 더 안전하고 편리합니다.
cfeduke

6
const의 장점은 스위치에서 사용할 수 있다는 것입니다.
knaki02

11

이것은 IMO가 가장 좋은 방법입니다. 속성 또는 읽기 전용이 필요하지 않습니다.

public static class Constants
{
   public const string SomeConstant = "Some value";
}

9
const를 사용하려면 내부 전용으로 노출하십시오. const를 공개하지 마십시오 (어셈블리가 조직 외부에서 사용되지 않을 것이라고 생각하는 경우에도). 또한 속성은 인터페이스를 재정의 할 필요없이 향후 확장을위한 프로그래밍 방식의 유연성을 제공합니다.
cfeduke

4

빈 정적 클래스가 적절합니다. 여러 클래스를 사용하여 하나의 거대한 Globals.cs 파일이 아닌 관련 상수의 좋은 그룹을 만들도록 고려하십시오.

또한 일부 int 상수의 경우 표기법을 고려하십시오.

[Flags]
enum Foo
{
}

이것은 flags와 같은 값처리 할 수 있도록 허용합니다 .


"여러 클래스를 사용하여 하나의 거대한 Globals.cs 파일이 아닌 관련 상수 그룹을 만들 수 있도록 고려하십시오." 이것이 최선의 권장 사항이라고 생각합니다. 주위에 디자인 패턴이 없습니까? 나는 이름으로 아무것도 몰라요?
greg

3

web.config 또는 app.config 사용에 대한 또 다른 투표. 구성 파일은 연결 문자열 등과 같은 상수를위한 좋은 장소입니다. 이러한 유형의 항목을 보거나 수정하기 위해 소스를 볼 필요가 없습니다. .config 파일에서 이러한 상수를 읽는 정적 클래스는 애플리케이션이 이러한 리소스에 코드에 정의 된 것처럼 액세스 할 수 있도록하지만 쉽게보고 편집 할 수있는 유연성을 제공하므로 좋은 절충안이 될 수 있습니다. 우주.


2
연결 문자열은 상수가 아니라 설정입니다. OP가 실제로 상수가 아닌 설정을 의미 할 수도 있지만 이에 대한 증거는 보이지 않습니다.
Jon Skeet

나는 다를 것을 간청한다. 문자열 리터럴은 정의상 상수입니다. 구성 파일에서 문자열을 변경하는 것은 코드에서 변경하고 다시 컴파일하는 것과 거의 동일합니다. 겠습니까 이 일정하지 만들? 나는 그렇게 생각하지 않는다.
3Dave 2009

2
@David-사실이 아닙니다. 컴파일러는 구성 파일에있는 값에 대해 신경 쓰지 않습니다. 이것은 런타임에 읽 힙니다.
Philip Wallace

@PhilipW 이해합니다. 내 요점은 (Jon Skeet의 의견에 대한 응답으로) 모든 문자열 리터럴과 마찬가지로 특정 연결 문자열이 상수라는 것입니다. "상수"를 변경할 수 있다는 사실은 구성 파일을 수정하고 앱이 해당 구성 파일에서 새 값을 가져 오게하거나 재 컴파일 / 배포가 필요한 코드의 리터럴을 변경하여 변경할 수 있습니다. "설정"으로 만드십시오. 문자열 자체는 컨테이너에 관계없이 일정합니다. 나는 당신의 요점을 이해하고 동의합니다-단지 내가 말한 것이 아니 었습니다.
3Dave

1
내 경험상, 예상치 못한 미래의 어느 시점에서 당신의 "상수 한"가치는 당신이 백만년 안에 결코 없을 것이라고 생각하더라도 변해야 할 것입니다. 소스 코드를 변경하는 것보다 .config 파일에서 수행하는 것이 훨씬 쉽다고 생각합니다. 결국 모든 것이 설정이됩니다.
NinjaBomb

1

예, static class특정 유형과 관련된 상수를 제외하고는 상수를 저장하는 것이 좋습니다.


그게 바로 제가하려는 일입니다. 나는 그들이 그들이 원하는 클래스의 구성원으로 나타나기를 원합니다. 하지만 내가 일하는 회사에 따라 상수가 다르기 때문에 클래스에 추가하고 싶지 않습니다. 확장 상수 나 속성에 대해서는 아직 아무것도 찾지 못했습니다. 하지만 저는이 클래스를 연재 할 때 멤버로 표시되는 것을 원하지 않기 때문에이 아이디어를 포기할 수 있습니다
symbiont

0

이러한 상수가 응용 프로그램 동작에 영향을주는 서비스 참조 또는 스위치 인 경우이를 응용 프로그램 사용자 설정으로 설정합니다. 이렇게하면 변경해야하는 경우 다시 컴파일 할 필요가 없으며 정적 속성 클래스를 통해 계속 참조 할 수 있습니다.

Properties.Settings.Default.ServiceRef

0

정적 읽기 전용으로 정적 클래스를 제안합니다. 아래 코드 스 니펫을 찾으십시오.

  public static class CachedKeysManager
    {
        public static readonly string DistributorList = "distributorList";
    }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.