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 인 빈 배열을 갖는 것 입니다. hemantAlex 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.