다음과 비슷한 것을 쓸 수 있습니까?
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 };
답변
배열을 다음과 같이 선언 할 수 있습니다 readonly
있지만 readonly
array 요소를 변경할 수 있습니다 .
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 # .NET을 : 새로운 및 향상된 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";
답변
IReadOnlyList 인터페이스 뒤에 배열을 선언하면 런타임에 선언 된 상수 값을 가진 상수 배열을 얻습니다.
public readonly IReadOnlyList<string> Titles = new [] {"German", "Spanish", "Corrects", "Wrongs" };
.NET 4.5 이상에서 사용 가능합니다.
답변
.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
답변
내 필요 static
에 따라 불가능 대신 배열을 정의 const
하고 작동합니다.
public static string[] Titles = { "German", "Spanish", "Corrects", "Wrongs" };