Programming

const 배열 선언

procodes 2020. 2. 20. 23:38
반응형

const 배열 선언


다음과 비슷한 것을 쓸 수 있습니까?

public const string[] Titles = { "German", "Spanish", "Corrects", "Wrongs" };

예, 그러나 readonly대신 다음과 const같이 선언해야합니다 .

public static readonly string[] Titles = { "German", "Spanish", "Corrects", "Wrongs" };

그 이유는 const컴파일 타임에 값이 알려진 필드에만 적용 할 수 있기 때문입니다 . 표시 한 배열 이니셜 라이저는 C #에서 상수 표현식이 아니므로 컴파일러 오류가 발생합니다.

readonly이 값을 선언하면 런타임까지 값이 초기화되지 않기 때문에이 문제가 해결됩니다 (배열을 처음 사용하기 전에 초기화 된 것이 보장되지만).

궁극적으로 달성하고자하는 것이 무엇인지에 따라 열거 형 선언을 고려할 수도 있습니다.

public enum Titles { German, Spanish, Corrects, Wrongs };

array를로 선언 할 수 readonly있지만 readonlyarray 요소를 변경할 수 있습니다 .

public readonly string[] Titles = { "German", "Spanish", "Corrects", "Wrongs" };
...
Titles[0] = "bla";

Cody가 제안한대로 열거 형 또는 IList를 사용하십시오.

public readonly IList<string> ITitles = new List<string> {"German", "Spanish", "Corrects", "Wrongs" }.AsReadOnly();

배열은 객체이고 런타임에만 만들 수 있고 const 엔터티는 컴파일 타임에 확인되므로 'const'배열을 만들 수 없습니다.

대신 배열을 "읽기 전용"으로 선언하면됩니다. 런타임에 값을 설정할 수 있다는 점을 제외하면 const와 동일한 효과가 있습니다. 한 번만 설정할 수 있으며 이후 읽기 전용 (즉, const) 값입니다.


C # 6부터 다음과 같이 작성할 수 있습니다.

public static string[] Titles => new string[] { "German", "Spanish", "Corrects", "Wrongs" };

참조 : C 번호 : 새롭게 개선 된 C # 6.0 (특히 장 "표현 바디 기능 및 속성")

이렇게하면 읽기 전용 정적 속성이 만들어 지지만 여전히 반환 된 배열의 내용을 변경할 수 있지만 속성을 다시 호출하면 원래의 변경되지 않은 배열을 다시 얻게됩니다.

명확히하기 위해이 코드는 다음과 동일합니다 (또는 실제로는 속기).

public static string[] Titles
{
    get { return new string[] { "German", "Spanish", "Corrects", "Wrongs" }; }
}

이 방법에는 단점이 있습니다. 새로운 배열은 각각의 참조마다 실제로 인스턴스화되므로 매우 큰 배열을 사용하는 경우 가장 효율적인 솔루션이 아닐 수 있습니다. 그러나 동일한 배열을 재사용하면 (예를 들어 개인 속성에 배치하여) 배열의 내용을 변경할 가능성이 다시 열립니다.

불변 배열 (또는 목록)을 원한다면 다음을 사용할 수도 있습니다.

public static IReadOnlyList<string> Titles { get; } = new string[] { "German", "Spanish", "Corrects", "Wrongs" };

그러나 여전히 문자열 []로 다시 캐스팅하고 내용을 변경할 수 있으므로 변경의 위험이 있습니다.

((string[]) Titles)[1] = "French";

다른 접근법을 취할 수 있습니다 : 배열을 나타내는 상수 문자열을 정의한 다음 필요할 때 문자열을 배열로 분할하십시오.

const string DefaultDistances = "5,10,15,20,25,30,40,50";
public static readonly string[] distances = DefaultDistances.Split(',');

이 접근 방식은 구성에 저장하고 필요할 때 배열로 변환 할 수있는 상수를 제공합니다.

알라 스테 어


IReadOnlyList 인터페이스 뒤에 배열을 선언하면 런타임에 선언 된 상수 값을 가진 상수 배열을 얻습니다.

public readonly IReadOnlyList<string> Titles = new [] {"German", "Spanish", "Corrects", "Wrongs" };

.NET 4.5 이상에서 사용 가능합니다.


내 필요 static에 따라 불가능 대신 배열을 정의 const하고 작동합니다.public static string[] Titles = { "German", "Spanish", "Corrects", "Wrongs" };


.NET 프레임 워크 V4.5의 + 솔루션 에 향상 tdbeckett의 대답 :

using System.Collections.ObjectModel;

// ...

public ReadOnlyCollection<string> Titles { get; } = new ReadOnlyCollection<string>(
  new string[] { "German", "Spanish", "Corrects", "Wrongs" }
);

참고 : 컬렉션이 개념적으로 일정 static하면 클래스 수준 에서 컬렉션 을 선언하는 것이 좋습니다.

위 :

  • 배열을 사용 하여 속성의 암시 적 백업 필드를 한 번 초기화합니다 .

    • 하는 것으로 { get; }- 즉, 단지 속성 선언 게터을 - 암시 적으로 읽기 전용 속성 자체를 만드는 것입니다 (결합하는 시도 readonly와 함께하는 것은 { get; }실제로 구문 오류입니다).

    • 또는 질문에서와 같이 속성 대신 필드 를 생성하기 위해 { get; }및 추가 readonly생략 할 수 있지만 공개 데이터 멤버를 필드가 아닌 속성으로 노출 하는 것이 좋은 습관입니다.

  • 다음 과 관련하여 진정으로 강력하게 읽기 전용 (개념적으로 일정하고 일단 생성 된) 인 배열 과 유사한 구조 ( 인덱스 액세스 허용 )를 만듭니다 .

    • 컬렉션 의 전체 수정 방지 (예 : 요소를 제거 또는 추가하거나 변수에 새 컬렉션을 할당)
    • 개별 요소의 수정 방지 .
      (심지어 간접적으로 변형 불가능 -와는 달리 IReadOnlyList<T>용액 캐스트 요소에 대한 쓰기 액세스를 얻기 위해 사용될 수있다 같이 mjepsen의 도움 않음 . 동일한 취약점이 적용 인터페이스 이름 유사성에도 불구하고, 이는 로 클래스 , 심지어 지원하지 않는 인덱스 액세스를 액세스 어레이 형상 제공하는 것이 근본적으로 적합하지 않다.)(string[])
      IReadOnlyCollection<T> ReadOnlyCollection

이것은 원하는 것을 수행하는 방법입니다.

using System;
using System.Collections.ObjectModel;
using System.Collections.Generic;

public ReadOnlyCollection<string> Titles { get { return new List<string> { "German", "Spanish", "Corrects", "Wrongs" }.AsReadOnly();}}

읽기 전용 배열을 수행하는 것과 매우 유사합니다.


완전성을 위해 이제 우리는 또한 ImmutableArrays를 사용할 수 있습니다. 이것은 정말로 불변이어야합니다 :

public readonly static ImmutableArray<string> Tiles = ImmutableArray.Create(new[] { "German", "Spanish", "Corrects", "Wrongs" });

System.Collections.Immutable NuGet 참조 필요

https://msdn.microsoft.com/en-us/library/mt452182(v=vs.111).aspx


나는 당신이 그것을 읽기 전용으로 만들 수 있다고 생각합니다.


배열은 런타임시에만 평가할 수있는 것 중 하나 일 것입니다. 컴파일 타임에 상수를 평가해야합니다. "const"대신 "readonly"를 사용해보십시오.


대안으로, 읽기 전용 배열에서 수정할 수있는 요소를 해결하기 위해 정적 속성을 대신 사용할 수 있습니다. 개별 요소는 계속 변경할 수 있지만 이러한 변경 사항은 어레이의 로컬 사본에서만 수행됩니다.

public static string[] Titles 
{
    get
    {
        return new string[] { "German", "Spanish", "Corrects", "Wrongs"};
    }
}

물론 매번 새로운 문자열 배열이 만들어 지므로 이는 특히 효율적이지 않습니다.

참고 URL : https://stackoverflow.com/questions/5142349/declare-a-const-array



반응형