最大1万円超分の電子書籍プレゼント♪

初歩の質問で恐縮です。

配列の使い方で
 public string[] item; と宣言しておいて、
下記例のように配列の長さを最初に宣言せず、その都度値を代入して見かけ上長さを動的に変え、Lengthの値を使うのは正しいやり方なのでしょうか?

string test = "A,B,C";
item = test.Split(',');
int len1 = item.Length;
   .
.
.
test = "A,B,C,D";
item = test.Split(',');
int len2 = item.Length;
Console.WriteLine(" len1=" + len1 + " len2=" + len2);

結果 len1=3 len2=4

質問者からの補足コメント

  • 少し理屈?が理解できかけたような気がします。

    例えば
    public string[] item=new string[100];
    のように最初に宣言しても後から
    item=itemB
    のようにitemに他の配列itemBを代入すればitem.LengthはitemBのLengthと同じになるということでしょうか?

    No.3の回答に寄せられた補足コメントです。 補足日時:2021/05/28 16:15
  • ”参照”なんですね。C#配列は固定長だと思っていました。

    質問が多少変わりますが、他の配列を代入するのではなく、
     string test = "A,B,C";
     item = test.Split(',');
    のように新たに値を設定した場合はどのような扱いになるのでしょうか?
    以前の参照が廃棄されて宣言をし直したのと同じなのでしょうか?

    No.4の回答に寄せられた補足コメントです。 補足日時:2021/05/29 05:45
gooドクター

A 回答 (5件)

> ”参照”なんですね。

C#配列は固定長だと思っていました。
itemを可変長に宣言しているので、固定長ではありませんよね。
勿論、固定長に宣言したものに、上記コードを実施したらエラーになりますよ。
itemはSplit()結果を受けるための受け皿としてポインタを用意しているようなものです。(という表現の方が理解しやすいんでしょうか?)

> 質問が多少変わりますが、他の配列を代入するのではなく、
>  string test = "A,B,C";
>  item = test.Split(',');
> のように新たに値を設定した場合はどのような扱いになるのでしょうか?

全く同じ質問ですよね。
item変数に配列を代入していることに変わりはありません。
無駄にメモリを食うだけです。

こういうこと試したことありますか?
string[] item;
string test = "A,B,C";
item = test.Split(',');

string[] item2;
item2 = item;
item2[0] = "D";

Console.WriteLine($"{item[0]}, {item2[0]}");

結果は『D, D』となります。
itemとitem2が、いずれも同じメモリを参照していることが確認できると思います。

さらに、こういうこと試したことありますか?
string[] item;
string test = "A,B,C";
item = test.Split(',');

string[] item2;
item2 = test.Split(',');
item2[0] = "D";

Console.WriteLine($"{item[0]}, {item2[0]}");

結果は『A, D』と表示されます。
testを何度もSplit()すれば、その結果はすべて異なるメモリ領域扱いです。
2回目の代入先としてitemを指定すれば2回目Split()の実行結果が参照されることになり、元々参照されていた1回目Split()の実行結果へはアクセスできなくなります。

では1回目Split()の結果はどうなるのか?
プログラムの中ではアクセス不能な状態になり、メモリ上は消費していることになります。
ガベージコレクションによっていつかは開放されるものですが、明らかに無駄な動作です。
    • good
    • 0
この回答へのお礼

大変詳しい説明ありがとうございました。今まで深く考えず使用してきましたがソースコード全体を見直してみます。

ありがとうございました

お礼日時:2021/05/30 05:52

> 配列のLengthとはそういうものだと頭から信じ込んでたのですが、ネット


> で調べると固定かResizeなどという情報にだけしか出会わず心配しており
> ました。

質問にある内容は、配列の要素を追加しているわけではありません。
異なる配列情報でitem変数の参照先を書き換えている動作です。

用意された配列に対して、要素を追加・削除をしたいという話なら別ですが、
質問にある内容は変数値を差し替えているわけですから、追加・削除ではありませんよね。
Lengthプロパティは、現在の配列の要素数を得るためのものなので、どんな配列を参照しているのかで都度変わります。

追加、削除を行いたい場合は、ANo.2にある通り、List<T>クラスなどを利用した方が手間とコストはかかりません。
この回答への補足あり
    • good
    • 0

特に問題ありませんが、


配列の長さに見かけも本物もありません。

配列の長さは配列生成時に配列の長さを明示することで決まります。

配列型の変数の宣言自体には配列長はなく、
配列型の変数は配列の参照を保持するだけです。

配列型の変数には様々な長さの配列の「参照」を随時代入できます。
この回答への補足あり
    • good
    • 0

C#はよくしらないんですが、Javaとして考えると、動的配列 Listを使いましょう、であってるかな。



配列はサイズは固定だと思います。
詳しくは言語使用を見た方がいいですね。

まあ、Listの中身は固定配列で、足りなくなったら切りなおすという実装だと思いますけど。
    • good
    • 0

問題ありません。


ただし、その場合、1メソッド内にだらだらコードが書かれている状態だとしたら、itemの中身がどちらなのか判別きかなくなると思います。
そういう点で問題がないのなら、全く問題ありません。
    • good
    • 0
この回答へのお礼

ありがとうございました。安心しました。
配列のLengthとはそういうものだと頭から信じ込んでたのですが、ネットで調べると固定かResizeなどという情報にだけしか出会わず心配しておりました。
ご指摘いただいた判別については確認しようと思います。(ちょっと怪しい点が思い当たるので)

お礼日時:2021/05/28 15:54

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

gooドクター

このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング