public class Sample
{
static int count = 0;
public int abc;
public Sample()
{
abc = ++Sample.count;
}
}
上記のクラスの配列を作成し、配列の各要素をデフォルトのコンストラクターを呼び出すことによって初期化して、各要素が異なるabc
を持つことができるようにしたいので、これを行いました:
Sample[] samples = new Sample[100];
しかし、これは私がするべきだと私が思うことをしません。この方法では、デフォルトのコンストラクターが呼び出されないようです。配列を作成するときにデフォルトのコンストラクターを呼び出す方法は?
また、上記のステートメントの機能を教えてください。
基本的にはできません。配列を作成すると、配列には常にタイプのデフォルト値が常に入力されます-クラスの場合、これは常にnull参照です。 int
の場合は0、bool
の場合はfalseなどです。
(配列初期化子を使用する場合、「空の」配列が作成され、thenはもちろん、指定した値をこの配列に入力します。)
コンストラクターを呼び出すことで配列に値を設定するには、さまざまな方法があります。私はおそらく foreachループを自分で使用します。 Enumerable.Range/RepeatでLINQを使用すると、少し強制されたように感じます。
もちろん、拡張メソッドであっても、いつでもwrite独自のポピュレーションメソッドを使用できます。
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>
を取り、プロバイダーにインデックスを渡すオーバーロードコードはarrayのみを作成し、その項目は作成しません。基本的に、あなたはstore instances of Sample
intoこの配列にする必要があります。
簡単に言うと、派手なLINQなどはありません。
Sample[] samples = new Sample[100];
for (int i = 0; i < samples.Length; i++) samples[i] = new Sample();
また、ソリューションはnotスレッドセーフであることにも注意してください。
これを自動的に行う方法はありません。配列の初期化は基本的に「このメモリブロックを0にワイプ」します。あなたは次のようなことをしなければなりません:
var arr = new SomeType[size];
for(int i = 0 ; i < size ; i++) arr[i] = new SomeType();
問題は、その配列を宣言することにより、各オブジェクトにスペースを割り当てなかったことです。 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;
}
少し傷を隠します-これがあなたに役立つ機能を提供します。
この時点でサイズ100の空の配列があり、アイテムでそれを埋める場合は、次のようにする必要があります。
for(int i=0; i<samples.Length; i++) {
samples[i] = new Sample();
}
以下は、拡張メソッドを必要としない別のワンライナーです。
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();