C#で空の配列を初期化するにはどうすればよいですか?


328

サイズを指定せずに空の配列を作成することは可能ですか?

たとえば、私は作成しました:

String[] a = new String[5];

サイズなしで上記の文字列配列を作成できますか?


2
stackoverflow.com/questions/151936/…このリンクを確認してください。配列のことを明確に理解するのに役立つ場合があります
Ravi Gadag

回答:


435

サイズが事前にわからないコレクションを使用する場合は、配列よりも優れたオプションがあります。

List<string>代わりにa を使用してください。これにより、必要な数の項目を追加でき、配列を返す必要がある場合ToArray()は、変数を呼び出します。

var listOfStrings = new List<string>();

// do stuff...

string[] arrayOfStrings = listOfStrings.ToArray();

空の配列を作成する必要がある場合、これを行うことができます:

string[] emptyStringArray = new string[0]; 

1
@Oded-string [] emptyStringArray = new string [0]; 空の配列にはなりませんか?それはその要素がnullである1つの要素を持つ配列であるように見えます。
rory.ap 2013

11
@roryap-いいえstring[]。要素のないaになります。にアクセスしようとするemptyStringArray[0]と、IndexOutOfRangeException
Oded

@Oded-おかげで、私はC#にかなり慣れていません。VBでは、提供されるインデックスは上限であり、要素の数ではありません。
rory.ap 2013

1
あなたは何をより良く考えますか:var strings = new string [] {}; またはvar strings = new string [0]; ところで、私は空の配列をメソッドパラメータの完全に有効なデフォルトと見なしています。public void EditItems(IEnumerable <Item> toEdit、IEnumerable <long> toDelete = new long [] {})
realbart

6
@ RickO'Shea-C ++はC#ではありません。Stroustrupは彼のC ++を知っています-彼が自分のC#と.NET GCを知っているかどうかはわかりません。あなたと宗教戦争をするつもりはありません。
2017

181

これを試して:

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

7
この答えを拡張すると、サイズまたはタイプを指定せずに項目で配列を初期化することもできます。コンパイラーはイニシャライザから推測します。var a = new [] {"a"、 "b"、 "c"}; これはまだ強く型付けされた文字列配列です。
Nick VanderPyle

1
未処理の例外:System.IndexOutOfRangeException:インデックスが配列の境界外にありました。ArrayClass.Main(String [] args)。int [] variable = new int [] {}を変更した後、このエラーに直面しました
yogesh

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[]{}、両方が同じコードにコンパイルされるので、違いはありません。
いいえ、

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>();

実装が使用して、簡潔で一般的なクラスの静的メンバは.NETでどのように動作しますか

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-編集ありがとうございましたが、元に戻しました。意図的にこれらの行を省略しました。興味深い実装だけを引用したかったのです。コードコントラクトと属性は、何が起こっているかを理解する上で邪魔になります(もちろん、ソースへのリンクにはすべてが含まれています)。Stack Overflowでスクロールしないように、コメントに改行を追加しました。よろしければこの方法をお勧めします。ありがとう!
コビ

2
間違いなく、以下からの読みやすさの改善Enumerable.Empty<T>().ToArray()
DanielV '30

ほとんどの場合、この方法が確実に推奨されますが、元の質問には答えられません。OPは空の配列を作成しよとしています。配列を作成Array.Empty<T>()しませ。事前に割り当てられた配列への参照を返します。
l33t

33

サイズ0で初期化することもできますが、配列に追加できないため、サイズがわかっている場合は再初期化する必要があります。

string[] a = new string[0];

これが正解です
abzarak

7

サイズなしで配列を宣言してもあまり意味がありません。配列のサイズはおよそです。特定のサイズの配列を宣言するときは、物事を保持できるコレクションで使用可能なスロットの固定数を指定し、それに応じてメモリが割り当てられます。何かを追加するには、とにかく既存の配列を再初期化する必要があります(配列のサイズを変更する場合でも、このスレッドを参照してください)。空の配列を初期化するまれなケースの1つは、配列を引数として渡すことです。

コレクションのサイズがわからない場合にコレクションを定義する場合は、配列を選択するのではなく、のようなものを選択しますList<T>

つまり、サイズを指定せずに配列を宣言する唯一の方法は、サイズ0の空の配列を持つことです。hemantAlex Dnは2つの方法を提供します。別のより簡単な代替策は、単に次のことです

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 2015

たとえば、IEnumerableを返すいくつかのクラスによって実装されたインターフェイスがあり、実装の1つにメソッドの要素がなく、たとえば空の配列が返されます。
Ignacio Soler Garcia

@IgnacioSolerGarcia非常にパフォーマンスが重要なアプリケーションである場合に限り、その場合に配列を返します。配列は古くなっているので、可能であれば避けてください。参照してくださいリペットすることによって、これをして、このSOの質問
nawfal

返されるタイプはIEnumerableであるため、配列は読み取り専用であり、変更することを意図していないことに注意してください。たとえば、この場合にリストを返すのはなぜですか?
Ignacio Soler Garcia

1
空の配列の使用例は単純です-オブジェクトでそれを埋めたいが、何個追加するかわからない場合!
vapcguy 2015年

6

シンプルでエレガント!

string[] array = {}

大文字にするとキーワードなので、に変更arrayします。大文字と小文字が異なる場合でも、変数名としてキーワード名を使用するのはよくない習慣です。そして、私がそこにいたことを除いて、基本的に私の答えと同じです。aarrayString.Empty
vapcguy

1
1.配列はC#キーワードではありません。配列はクラスであり、キーワードではありません。2。「a」も悪い習慣です(おそらくキーワードを使用するよりも悪い習慣です)
disklosr

技術的であること。クラス、キーワード、それはオブジェクト型を定義し、まだ悪いです。なぜa悪いと思いますか?
vapcguy

1
非説明的で1文字の変数名は、それらを定義する背後にある理由を伝えないため、悪い習慣です。「配列」は確かに「a」よりも良い名前です。より適切な名前は「emptyArray」です。
disklosr

4

string[] a = new string[0];

または短い表記:

string[] a = { };

現在の推奨方法は次のとおりです。

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

たとえば長さゼロの割り当てを置き換える場合に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];
ケビン・ブロック

まあ、私はジェネリックでこれが時代遅れであるように思われると思います。
radarbob

2

私は試しました:

string[] sample = new string[0];

しかし、1つの文字列しか挿入できず、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プレビュー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プレビュー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は、サイズを指定する必要がないことを意味、配列しないsizelessを


8
これは長さ1の文字列配列を作成しませんか?
Sumner Evans

本当ですが、クリアされました。そしてOPはサイズを述べる必要なしに配列を宣言するように求めました-これはそれに適合します。
vapcguy 2015年

そして、それは反対の投票に値します、なぜですか?OPはspecify、配列を作成するのではなく、サイズを指定する必要がないことを意味しsizelessます。
vapcguy 2015年

1
@vapcguy私は反対投票者でした。私はそれを後悔します。私はあなたの回答を編集して私の反対投票をキャンセルしました。あなたのコメントは質問を少し疑わしくします。それがOPの意味するものかどうかはわかりません。
naffal

4
OPは空の配列を要求しました。この配列は空ではありません。
キース

0

これが実際の例です。この場合、foundFiles最初に配列をゼロ長に初期化する必要があります。

(他の回答で強調したように、これは要素ではなく、特にインデックス0の要素を初期化しません。これは、配列の長さが1であることを意味するためです。この行の後、配列の長さはゼロです!)。

パーツ= string[0]が省略されている場合、コンパイルエラーが発生します。

これは、再スローのないキャッチブロックが原因です。C#コンパイラはコードパスを認識し、関数Directory.GetFiles()が例外をスローできるため、配列が初期化されない可能性があります。

誰もが言う前に、例外を再スローしないと、エラー処理が悪くなります。これは真実ではありません。エラー処理は要件を満たす必要があります。

この場合、プログラムは、読み取ることができず、破損していない場合でも続行する必要があると想定されます。最良の例は、ディレクトリ構造をたどる関数です。ここでエラー処理はそれをログに記録するだけです。もちろん、これはもっとうまくできます。たとえば、失敗したGetFiles(Dir)呼び出しのあるすべてのディレクトリをリストに収集することはできますが、これはここまで行き過ぎです。

回避throwは有効なシナリオであり、配列は長さゼロに初期化する必要があると述べるだけで十分です。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.