- PR -

参照型のオブジェクトの配列

投稿者投稿内容
キョウ
常連さん
会議室デビュー日: 2003/04/30
投稿数: 49
投稿日時: 2003-07-10 10:24
SqlParameter[] sqlPrm = new SqlParameter[4];
sqlPrm[0].Direction = ParameterDirection.Input;

上記の処理を行った際に二行目で、「オブジェクト参照がオブジェクトインスタンスに
設定されていません。」というエラーになってしまいます。
参照型のオブジェクトの配列の宣言は一行目でオブジェクトの実体が生成されるのでは
ないのでしょうか?
cats
大ベテラン
会議室デビュー日: 2002/11/29
投稿数: 221
お住まい・勤務地: 東京
投稿日時: 2003-07-10 10:56
参照型の場合、配列オブジェクトはnullで初期化されて作成されます。
(配列の指している先は作成されません。)
キョウ
常連さん
会議室デビュー日: 2003/04/30
投稿数: 49
投稿日時: 2003-07-10 12:09
コード:
SqlParameter[] sqlPrm = new SqlParameter[2];
sqlPrm[0] = new SqlParameter();
sqlPrm[1] = new SqlParameter();

sqlPrm[0].Direction = ParameterDirection.Input;



上記の記述でうまくいきました。ありがとうございます。

一行目を
SqlParameter[2] sqlPrm;
とするとコンパイルを通らないので、上記の形にしましたが、
どうもだぶってオブジェクトをnewしているように感じてしまうのですが、
どこか私の理解が間違っているのでしょうか?
cats
大ベテラン
会議室デビュー日: 2002/11/29
投稿数: 221
お住まい・勤務地: 東京
投稿日時: 2003-07-10 13:31
間違っていません。
大丈夫です。
なちゃ
ぬし
会議室デビュー日: 2003/06/11
投稿数: 872
投稿日時: 2003-07-10 13:42
引用:

SqlParameter[] sqlPrm = new SqlParameter[2];
sqlPrm[0] = new SqlParameter();
sqlPrm[1] = new SqlParameter();

sqlPrm[0].Direction = ParameterDirection.Input;

SqlParameter[2] sqlPrm;
とするとコンパイルを通らないので、上記の形にしましたが、
どうもだぶってオブジェクトをnewしているように感じてしまうのですが、
どこか私の理解が間違っているのでしょうか?


上の例では new が3回実行されていますね。
参照型の配列オブジェクトは、明示的に値を設定するまで null になっています。

今回の場合、new する必要のあるオブジェクトは、
・配列の実体1つ(容器の実体、入れ物そのものと考えてください)
・配列に入れるものの実態2つ

重要な点は、
・配列は明示的に入れ物の実体を作成しなければならない(変数宣言だけでは駄目)
・配列を作成してもその中身は空であり、格納するものは別途用意する必要がある
# {} で初期化する場合は中身の格納も同時にできますが、
# やはり格納する物自体は、別途用意する必要があります。

SqlParameter[] sqlPrm = new SqlParameter[2];
この場合サイズが2の入れ物を用意しただけで、入れ物の中身は空ということです。
キョウ
常連さん
会議室デビュー日: 2003/04/30
投稿数: 49
投稿日時: 2003-07-10 18:07
参照型の場合の配列の仕方が明確にわかりました。
ありがとうございます。


コード:
string[] strHoge = new string[3];



の場合、特に後からそれぞれの配列毎にnewしていない事が理解を妨げて
いる原因でした。string型の時には、
コード:
string strHoge;
strHoge = "hogehoge";


という形でも使えている事からstringは特にnewする事が必要なく、
string型に関しては、参照型の中でも特例と思ったほうがいいのでしょうか?
そうするとスッキリします。
なちゃ
ぬし
会議室デビュー日: 2003/06/11
投稿数: 872
投稿日時: 2003-07-10 22:25
引用:

string[] strHoge = new string[3];
の場合、特に後からそれぞれの配列毎にnewしていない事が理解を妨げて
いる原因でした。string型の時には、
string strHoge;
strHoge = "hogehoge";
という形でも使えている事からstringは特にnewする事が必要なく、
string型に関しては、参照型の中でも特例と思ったほうがいいのでしょうか?


string 型についても、配列に関する扱いは他の参照型と変わりません。ただし、string 型は new を明示的に使用しなくてもインスタンスを生成できるという違いがあります。
プログラム中に "hogehoge" と記述すると、他の参照型で new を使った場合のように、インスタンスが生成されてその参照が返されます。
# 実際には、リテラルの文字列は生成のされ方がやや特殊だったかも。
# でも実質的には文字列を書くだけで、new でインスタンスを生成するのとほぼ同じ。

配列の場合は、たとえば
string[] strHoge = new string[2];
strHoge[0] = "hoge";
strHoge[1] = "hogehoge";
みたいな感じになります({}で直接初期化しない場合)。
格納する実体は、new を使わずにリテラルで直接インスタンス化しています。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2003-07-11 08:43
引用:

なちゃさんの書き込み (2003-07-10 22:25) より:

格納する実体は、new を使わずにリテラルで直接インスタンス化しています。


 そういえば、「リテラル」という言葉を、その言葉の意味を知らずに使っていたなぁ…
と、思って辞書を引くと、、、
引用:
『EXCEED英和辞典』
lit・er・al

a. 文字(どおり)の; 逐語的な; 正確な; 装飾のない; 字句にとらわれた, 散文的な; アルファベットの[による]; 【印】活字の.

n. 【印】誤字, 誤植; 【コンピュータ】リテラル, 直定数.



 MSDNの「Visual C# 言語仕様 2.4.4 リテラル」にありますが、
これらは「直」に「定数」として機能します。←そのままやんけ!
stringと同じように、intやfloatも、newしませんよね。
私のC言語的な理解では、
ソースファイルをオブジェクトファイルにコンパイルする時点で、
それようにメモリが確保されている。。。のかなぁ?

スキルアップ/キャリアアップ(JOB@IT)