20
public class Sample
{
     static int count = 0;
     public int abc;
     public Sample()
     {
        abc = ++Sample.count;
     }
}

上記のクラスの配列を作成し、配列内の各要素をデフォルトのコンストラクターを呼び出して初期化して、各要素が異なるようにしたいので、次のようabcにしました。

Sample[] samples = new Sample[100];

しかし、これは私がすべきだと思うことをしません。このように、デフォルトのコンストラクターが呼び出されていないようです。配列を作成するときにデフォルトコンストラクタを呼び出す方法は?

また、上記のステートメントが何をするのか知りたいですか?

4

6 に答える 6

46

基本的に、できません。配列を作成すると、最初は常に型のデフォルト値が入力されます。クラスの場合、これは常に null 参照です。int0、偽boolなどです。

(配列初期化子を使用すると、「空の」配列が作成され、指定し値が入力されます。)

コンストラクターを呼び出して配列を設定する方法はいくつかあります。おそらく、自分で foreach ループを使用するだけです。Enumerable.Range/Repeat での LINQ の使用は、少し強制されているように感じます。

もちろん、拡張メソッドであっても、いつでも独自の人口メソッドを作成できます。

public static T[] Populate<T>(this T[] array, Func<T> provider)
{
    for (int i = 0; i < array.Length; i++)
    {
        array[i] = provider();
    }
    return array;
}

次に、次を使用できます。

Sample[] samples = new Sample[100].Populate(() => new Sample());

このソリューションの気に入っているところ:

  • これはまだ単一の式であり、さまざまなシナリオで役立ちます
  • 実際に必要のない概念は導入されません (単一の値の繰り返しや範囲の作成など)。

もちろん、さらにオプションを追加することもできます:

  • Func<int, T>の代わりにを受け取りFunc<T>、インデックスをプロバイダに渡すオーバーロード
  • 配列を作成して設定する非拡張メソッド
于 2011-01-29T21:19:19.957 に答える
9

コードはarrayのみを作成し、その項目は作成しません。基本的に、 のインスタンスをこの配列に格納する必要Sample あります。

派手なLINQなどを使わずに、簡単に言えば:

Sample[] samples = new Sample[100];
for (int i = 0; i < samples.Length; i++) samples[i] = new Sample();

また、ソリューションはスレッドセーフではないことに注意してください。

于 2011-01-29T21:19:01.857 に答える
4

これを自動的に行う方法はありません。配列の初期化は、基本的に「このメモリ ブロックを 0 に消去する」ことです。あなたは次のようなことをしなければならないでしょう:

var arr = new SomeType[size];
for(int i = 0 ; i < size ; i++) arr[i] = new SomeType();
于 2011-01-29T21:18:58.073 に答える
2

この時点で、サイズ 100 の空の配列があります。項目で埋めたい場合は、次のようにする必要があります。

for(int i=0; i<samples.Length; i++) {
   samples[i] = new Sample();
}
于 2011-01-29T21:24:15.217 に答える
2

問題は、その配列を宣言することによって、各オブジェクトにスペースを割り当てなかったことです。タイプ Sample の 100 個のオブジェクトにスペースを割り当てただけです。それぞれでコンストラクターを呼び出す必要があります。

詳しく説明するには:

Food[] foods = Food[100];
for (int k = 0; k < foods.length; k++) {
   foods[k] = new Food();
}

興味深い回避策は、ファクトリ関数です。これを Sample クラスにアタッチすることを検討してください。

public static Sample[] getInstances(int aNumber) {
    Sample[] sample = Sample[aNumber];
    for (int k = 0; k < sample.length; k++) {
       sample[k] = new Sample();
    }

    return sample;
}

傷を少し隠します - これがあなたにとって便利な機能であれば。

于 2011-01-29T21:19:03.170 に答える
1

これは、拡張メソッドを必要としない別のワンライナーです。

Sample[] array = Enumerable.Range(0, 100).Select(i => new Sample()).ToArray();

別の良いオプションは、ジョンの答えに対するスコットの提案です。

public static T[] Populate<T>(this T[] array) 
    where T : new()
{
    for (int i = 0; i < array.Length; i++)
        array[i] = new T();
    return array;
}

したがって、次のことができます。

Sample[] array = new Sample[100].Populate();
于 2014-07-10T08:36:34.173 に答える