C #에서 빈 배열을 어떻게 초기화합니까?


328

크기를 지정하지 않고 빈 배열을 만들 수 있습니까?

예를 들어, 나는 다음을 만들었습니다.

String[] a = new String[5];

크기없이 위의 문자열 배열을 만들 수 있습니까?


2
stackoverflow.com/questions/151936/… u이 링크를 확인하면 배열을 명확하게 이해하는 데 도움이 될 수 있습니다.
— Ravi Gadag

답변:


435

미리 크기를 모르는 컬렉션을 사용하려는 경우 배열보다 더 나은 옵션이 있습니다.

List<string>대신 사용하십시오 -필요한만큼 항목을 추가 할 수 있으며 배열을 리턴해야하는 경우 ToArray()변수를 호출 하십시오.

var listOfStrings = new List<string>();

// do stuff...

string[] arrayOfStrings = listOfStrings.ToArray();

당신이 경우 해야한다 하늘의 배열을 만들려면이 작업을 수행 할 수 있습니다 :

string[] emptyStringArray = new string[0]; 

1
@Oded-문자열 [] emptyStringArray = 새 문자열 [0]; 빈 배열이되지 않습니까? 해당 요소가 null 인 요소가 하나 인 배열 인 것 같습니다.
— rory.ap

11
@roryap-아니요 string[]. 요소가없는 결과입니다 . 에 액세스하려고하면 다음 emptyStringArray[0]과 같이됩니다.IndexOutOfRangeException
— Oded

@Oded-감사합니다. 저는 C #을 처음 접했습니다. VB에서 제공된 인덱스는 요소 수가 아니라 상한입니다.
— rory.ap

1
더 나은 점은 무엇입니까? var strings = new string [] {}; 또는 var strings = 새 문자열 [0]; BTW : 빈 배열을 메소드 매개 변수에 대해 완벽하게 유효한 기본값으로 생각합니다. public void EditItems (IEnumerable <Item> toEdit, IEnumerable <long> toDelete = new long [] {})
— realbart

6
@ RickO'Shea-C ++은 C #이 아닙니다. Stroustrup은 자신의 C ++에 대해 잘 알고 있습니다. C #과 .NET GC에 대해서는 잘 모릅니다. 당신과 종교 전쟁에 참여하지 않을 것입니다.
— 오디드

181

이 시도:

string[] a = new string[] { };

7
이 답변을 확장하면 크기 또는 유형을 지정하지 않고 항목을 사용하여 배열을 초기화 할 수 있습니다. 컴파일러는 초기화 프로그램에서 다음 중 하나를 유추합니다. var a = new [] { "a", "b", "c"}; 이것은 여전히 ​​강력한 형식의 문자열 배열입니다.
— Nick VanderPyle

1
처리되지 않은 예외 : System.IndexOutOfRangeException : 인덱스가 배열의 바운스 범위를 벗어났습니다. ArrayClass.Main (String [] args)에서 내 int [] 변수 = new int [] {}를 변경 한
— 후이

6
@yogesh : 이상합니다. 예를 들면 기록 할 때 int[] variable = new int[]{}와 같은 루프 예를 사용 foreach (var s in variable){ Console.WriteLine(s);}하는 코드로 컴파일된다 : int[] args1 = new int[0];및 foreach (int num in args1){Console.WriteLine(num);}. 그래서 사용하는 사이에 차이점이 없습니다 new int[0]와 new int[]{}같은 코드로 컴파일 모두 GET있다.
— Nope

1
@GlennGordon 물론, C # 버전 3.0 (2007 년부터 Visual Studio 2008 포함)부터는 새로운 기능입니다. 이 버전은 var필드가 아닌 로컬 변수에만 해당되지만을 사용하여 또 다른 간단한 형식을 허용 합니다. 그러나 C # 2.0 (Visual Studio 2005) 및 이전 버전에서는이 답변의 구문 (또는 string[] a = new string[0];) 을 사용해야했습니다 .
— Jeppe Stig Nielsen

113

.NET 4.6에서 선호되는 방법은 다음과 같은 새로운 방법을 사용하는 것입니다 Array.Empty.

String[] a = Array.Empty<string>();

구현 하여, 간결이다 일반적인 클래스의 정적 멤버 닷넷에서 어떻게 행동하는지 :

public static T[] Empty<T>()
{
    return EmptyArray<T>.Value;
}

// Useful in number of places that return an empty byte array to avoid
// unnecessary memory allocation.
internal static class EmptyArray<T>
{
    public static readonly T[] Value = new T[0];
}

(명확성을 위해 코드 계약 관련 코드가 제거됨)

또한보십시오:


@Cole Johnson-편집 해 주셔서 감사하지만 롤백했습니다. 나는 의도적 으로이 줄을 생략했습니다 : 흥미로운 구현을 인용하고 싶었습니다. 코드 계약과 속성은 무슨 일이 일어나고 있는지 이해하는 방식에 불과합니다 (물론 소스 링크에는 모든 것이 있습니다). 또한 스택 오버플로에서 스크롤을 피하기 위해 주석에 줄 바꿈을 추가했습니다. 마음에 들지 않으면이 방법을 선호합니다. 감사!
— Kobi

2
다음과 같은 가독성 향상 :Enumerable.Empty<T>().ToArray()
— DanielV

이 방법은 대부분의 경우에 선호되지만 원래 질문에 대한 답은 아닙니다. OP는 빈 배열 을 만들려고 합니다. Array.Empty<T>()않습니다 하지 배열을 만들 수 있습니다. 미리 할당 된 배열에 대한 참조를 반환합니다.
— l33t

33

크기를 0으로 초기화 할 수는 있지만 크기를 알면 배열에 추가 할 수 없으므로 크기를 다시 초기화해야합니다.

string[] a = new string[0];

정답입니다
— abzarak

7

크기가없는 배열을 선언하는 데는 아무런 의미가 없습니다. 배열 은 대략 size 입니다. 특정 크기의 배열을 선언 할 때 콜렉션을 보유 할 수있는 고정 슬롯 수를 지정하면 메모리가 할당됩니다. 그것에 무언가를 추가하려면 어쨌든 기존 배열을 다시 초기화해야합니다 (배열의 크기를 조정 하더라도이 스레드를 참조하십시오 ). 빈 배열을 초기화하려는 드문 경우 중 하나는 배열을 인수로 전달하는 것입니다.

가능한 크기를 모를 때 컬렉션을 정의하려면 배열을 선택하는 것이 아니라 List<T>비슷한 것을 선택하십시오 .

즉, size를 지정하지 않고 배열을 선언하는 유일한 방법은 크기가 0 인 빈 배열을 갖는 것 입니다. hemant 와 Alex Dn 은 두 가지 방법을 제공합니다. 또 다른 간단한 대안은 다음과 같습니다.

string[] a = { };

[ 괄호 안의 요소는 예를 들어 정의 된 유형으로 암시 적으로 변환 가능해야합니다.string[] a = { "a", "b" }; ]

또는 또 다른 :

var a = Enumerable.Empty<string>().ToArray();

보다 선언적인 방법은 다음과 같습니다 .

public static class Array<T>
{
    public static T[] Empty()
    {
        return Empty(0);
    }

    public static T[] Empty(int size)
    {
        return new T[size];
    }
}

이제 전화를 걸 수 있습니다 :

var a = Array<string>.Empty();

//or

var a = Array<string>.Empty(5);

1
배열을 매개 변수로 전달해야 할 때를 제외하고는 사용을 생각할 수 없습니다. 메소드가 객체의 배열을 받아들이고 빈 배열을 전달하여 기본 동작에 영향을 줄 수있는 경우가 몇 가지 있습니다. 답변을 편집하겠습니다.
— nawfal

예를 들어 IEnumerable을 반환하는 여러 클래스로 구현 된 인터페이스가 있으며 구현 중 하나에는 메서드에 대한 요소가 없으며 빈 배열을 반환합니다.
— Ignacio Soler Garcia 9

@IgnacioSolerGarcia이 경우 성능이 매우 중요한 응용 프로그램 인 경우에만 배열을 반환합니다. 배열이 오래되었다고 말할 수 있다면 피해야합니다. 참조 Lippert의하여이 작업을 하고 이 SO 질문
— nawfal

반환 된 형식은 IEnumerable이므로 배열은 읽기 전용이며 변경하지 않아야합니다. 예를 들어이 경우 왜 List를 반환합니까?
— Ignacio Soler Garcia

1
빈 배열의 사용 사례는 간단합니다. 객체로 채우고 싶을 때 얼마나 추가 할 것인지 모릅니다!
— vapcguy

6

간단하고 우아한!

string[] array = {}

대문자로 입력하면 키워드 와 마찬가지로 arrayjust로 변경 됩니다 . 대소 문자가 다르더라도 키워드 이름을 변수 이름으로 사용하는 것은 좋지 않습니다. 그리고 기본적으로 내가 가진 것을 제외하고는 내 대답과 동일 합니다. aarrayString.Empty
— vapcguy 2016 년

1
1. 배열이 ac # 키워드가 아닙니다. 배열은 키워드가 아닌 클래스입니다. "a"도 나쁜 습관입니다 (키워드를 사용하는 것보다 나쁜 습관이 더 나쁠 수도 있습니다)
— disklosr

기술적 인 것. 클래스, 키워드는 객체 유형을 정의하지만 여전히 나쁩니다. 왜 a나쁘다고 생각 합니까?
— vapcguy

1
설명 적이 지 않고 한 글자로 된 변수 이름은 그것들을 정의한 이유를 전달하지 않기 때문에 나쁜 습관입니다. "배열"은 "a"보다 확실히 더 나은 이름입니다. 더 좋은 이름은 "emptyArray"입니다.
— disklosr 2016 년

4

string[] a = new string[0];

또는 짧은 표기법 :

string[] a = { };

현재 선호되는 방법은 다음과 같습니다.

var a = Array.Empty<string>();

길이가 0 인 할당을 바꾸려면 Visual Studio에서 사용할 수있는 짧은 정규 표현식을 작성했습니다 new string[0]. 정규식 옵션을 설정 한 상태로 Visual Studio에서 찾기 (검색)를 사용하십시오.

new[ ][a-zA-Z0-9]+\[0\]

이제 모두 또는 F3 (다음 찾기)을 찾아 모두 Array.Empty <…> ()로 바꾸십시오!


3

런타임시 배열 크기를 정의 할 수 있습니다 .

이를 통해 배열의 크기를 동적으로 계산할 수 있습니다. 그러나 일단 정의되면 크기는 불변입니다.

Array a = Array.CreateInstance(typeof(string), 5);

4
왜 그렇게합니까? 런타임에 변수에서 일반적으로 배열 크기를 정의 할 수 있습니다.int i = 5; string[] a = new string[i];
— Kevin Brock

글쎄, 제네릭을 사용하면 이것이 쓸모없는 것으로 보입니다.
— radarbob

2

나는 시도했다 :

string[] sample = new string[0];

그러나 하나의 문자열 만 삽입 할 수 있었고 exceptionOutOfBound 오류가 발생하여 단순히 크기를 입력하십시오.

string[] sample = new string[100];

또는 나를 위해 일하는 다른 방법 :

List<string> sample = new List<string>();

목록에 값 할당 :

sample.Add(your input);

1

아시다시피 크기없이 배열을 만들 수는 없지만 사용할 수는 있습니다

List<string> l = new List<string>() 

다음 l.ToArray().


1

@nawfal 및 @Kobi 제안 결합 :

namespace Extensions
{
    /// <summary> Useful in number of places that return an empty byte array to avoid unnecessary memory allocation. </summary>
    public static class Array<T>
    {
        public static readonly T[] Empty = new T[0];
    }
}

사용 예 :

Array<string>.Empty

업데이트 2019-05-14

(@Jaider ty의 신용)

.Net API를 더 잘 사용하십시오.

public static T[] Empty<T> ();

https://docs.microsoft.com/en-us/dotnet/api/system.array.empty?view=netframework-4.8

적용 대상 :

.NET Core : 3.0 Preview 5 2.2 2.1 2.0 1.1 1.0

.NET Framework : 4.8 4.7.2 4.7.1 4.7 4.6.2 4.6.1 4.6

.NET 표준 : 2.1 Preview 2.0 1.6 1.5 1.4 1.3

...

HTH


1
.NET Core 2에는 이미 확장 기능이 있습니다.arr = Array.Empty<string>();
— Jaider

iirc, .NetStandart [4.something]-또한 있습니다.
— ShloEmi

0

넌 할 수있어:

string[] a = { String.Empty };

참고 : OP는 크기를 지정할 필요가 없으며 배열을 크기가 없도록 만듭니다.


7
이것은 길이가 1 인 문자열 배열을 생성하지 않습니까?
— Sumner Evans

사실이지만 지워졌습니다. 그리고 OP는 크기를 명시하지 않고도 배열을 선언하도록 요청했습니다.
— vapcguy

그리고 그것은 공감할 가치가있는 이유는 무엇입니까? OP specify는 크기가 필요하지 않고 배열을 만들지 않았습니다 sizeless.
— vapcguy

1
@vapcguy 나는 downvoter였습니다. 나는 후회 해. 다운 보트를 취소하기 위해 답변을 수정했습니다. 귀하의 의견은 질문을 조금 모호하게 만듭니다. 그것이 OP가 무엇인지 확실하지 않습니다.
— nawfal

4
OP가 빈 배열을 요청했습니다 . 이 배열은 비어 있지 않습니다.
— Keith

0

여기 실제 사례가 있습니다. 이 경우 배열을 foundFiles먼저 길이를 0 으로 초기화해야합니다 .

(다른 답변에서 강조한 것처럼 : 이것은 요소가 아니라 특히 인덱스가 0 인 요소를 초기화하지 않습니다. 왜냐하면 배열의 길이가 1임을 의미하기 때문입니다. 배열은이 줄 뒤에 길이가 0입니다!).

부분 = string[0]이 생략되면 컴파일러 오류가 있습니다!

이것은 다시 던지지 않은 캐치 블록 때문입니다. C # 컴파일러는 코드 경로를 인식하여 함수 Directory.GetFiles()가 예외를 발생시켜 배열을 초기화 할 수 없도록합니다.

누군가 말하기 전에 예외를 다시 발생시키지 않으면 오류 처리가 잘못 될 수 있습니다. 이것은 사실이 아닙니다. 오류 처리는 요구 사항에 맞아야합니다.

이 경우, 읽을 수없는 디렉토리의 경우 프로그램이 계속 진행되어야한다고 가정합니다. 가장 좋은 예는 디렉토리 구조를 순회하는 함수입니다. 여기서 오류 처리는 단지 로깅입니다. 물론 이것은 GetFiles(Dir)목록에서 호출 이 실패한 모든 디렉토리를 수집하는 것과 같이 더 잘 수행 될 수 있지만, 여기에서는 너무 멀어 질 것입니다.

회피 throw는 유효한 시나리오 라고 말하면 충분 하므로 배열의 길이는 0으로 초기화해야합니다. catch 블록에서 이것을 수행하는 것으로 충분하지만 이것은 나쁜 스타일입니다.

GetFiles(Dir)배열 크기를 조정하는 호출

string[] foundFiles= new string[0];
string dir = @"c:\";
try
{
    foundFiles = Directory.GetFiles(dir);  // Remark; Array is resized from length zero
}
// Please add appropriate Exception handling yourself
catch (IOException)
{
  Console.WriteLine("Log: Warning! IOException while reading directory: " + dir);
  // throw; // This would throw Exception to caller and avoid compiler error
}

foreach (string filename in foundFiles)
    Console.WriteLine("Filename: " + filename);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.