デフォルトのコンストラクターによる配列初期化
-
27-10-2019 - |
質問
public class Sample
{
static int count = 0;
public int abc;
public Sample()
{
abc = ++Sample.count;
}
}
上記のクラスの配列を作成し、デフォルトのコンストラクターを呼び出すことにより、配列内の各要素を初期化したいと考えています。 abc
。だから私はこれをしました:
Sample[] samples = new Sample[100];
しかし、これは私がすべきだと思うことをしません。このようにして、デフォルトのコンストラクターが呼び出されていないようです。配列を作成するときにデフォルトのコンストラクターを呼び出す方法は?
また、上記の声明は何をしているのか知りたいですか?
解決
基本的にはできません。配列を作成すると、最初は常にタイプのデフォルト値が入力されています。クラスの場合は常にヌルの参照です。為に int
それは0です bool
それは誤りなどです。
(配列初期イザーを使用すると、「空の」配列が作成され、 それから もちろん、指定した値を入力してください。)
コンストラクターを呼び出すことにより、配列に穴を開けるさまざまな方法があります - 私は おそらく 自分でforeachループを使用するだけです。列挙可能/繰り返しで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>
aの代わりにFunc<T>
, 、インデックスをプロバイダーに渡します - 配列を作成する非拡張メソッド と それを入力します
他のヒント
あなたのコードはのみを作成します 配列, 、しかし、そのアイテムはどちらもありません。基本的に、あなたはする必要があります インスタンスを保存します の Sample
の中へ この配列。
派手なlinqなどなしで、シンプルにするために:
Sample[] samples = new Sample[100];
for (int i = 0; i < samples.Length; i++) samples[i] = new Sample();
また、あなたのソリューションはそうであることに注意してください いいえ スレッドセーフ。
これを自動的に行う方法はありません。配列の初期化は、本質的に「このメモリブロックを0Sに拭いてください」です。あなたは次のようなことをしなければなりません:
var arr = new SomeType[size];
for(int i = 0 ; i < size ; i++) arr[i] = new SomeType();
この時点で、サイズ100の空の配列があります。アイテムを埋めたい場合は、次のようなことをする必要があります。
for(int i=0; i<samples.Length; i++) {
samples[i] = new Sample();
}
問題は、その配列を宣言することで、各オブジェクトにスペースを割り当てないことです。タイプサンプルの100個のオブジェクトにスペースを割り当てただけです。あなたはそれぞれのコンストラクターに電話する必要があります。
詳しく説明する:
Food[] foods = Food[100];
for (int k = 0; k < foods.length; k++) {
foods[k] = new Food();
}
興味深い仕事は工場機能かもしれません。これをサンプルクラスに添付することを検討してください。
public static Sample[] getInstances(int aNumber) {
Sample[] sample = Sample[aNumber];
for (int k = 0; k < sample.length; k++) {
sample[k] = new Sample();
}
return sample;
}
傷を少し隠します - これを提供することはあなたにとって有用な機能です。
これは、拡張方法を必要としない別の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();