C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[2]: objectの内容が勝手に変わってしまいます


(過去ログ 87 を表示中)

[トピック内 3 記事 (1 - 3 表示)]  << 0 >>

■51803 / inTopicNo.1)  objectの内容が勝手に変わってしまいます
  
□投稿者/ 裕猫 (146回)-(2010/07/20(Tue) 16:51:37)

分類:[C#] 

WindowsXP VisualStudio2008C# で開発しています。
        public static Object[] OJ = new Object[200];  //-----------------------------------------------------------------------読み込みデータ
        public static Object[] NJ = new Object[200];  //-----------------------------------------------------------------------書き込みデータ

        public static int DBF(string DBN, string KYN, string STS, int TLO)
        {
            int X = 0;
            using (OracleConnection con = new OracleConnection())
            {
                con.ConnectionString = MKST.UID;
                try
                {
                    con.Open();
                }
                catch (Exception EX)
                {
                    MessageBox.Show("「" + EX.Message + "」でデータベースの接続に失敗しました。");
                    return X;
                }
                OracleCommand cmd = con.CreateCommand();
                cmd.CommandText = "select * from " + DBN + " where " + KYN + "ORDER BY " + STS;
                OracleDataReader dr = cmd.ExecuteReader();
                try
                {
                    dr.Read();
                    for (int CT1 = 0; CT1 < TLO; CT1++)
                    {
                        MKST.OJ[CT1] = dr[CT1];
                    }
                    X = 1;
                }
                catch
                {
                    X = 0;
                }
            }
            return X;
        }
でオラクルから読んだデータをOJオブジェクトに保持します。

        private void SKen(string SNa)
        {
            string WS, PS;
            //int FG3;
            int GI = 1;
            FG1 = CDBA.DBF("製品構成", "品番 = '" + SNa + "'", "品番,部番", AAAT);
            while (FG1 == 1)
            {
                if (FG1 == 0) { break; }
                //FG3 = 0;
                for (int CT1 = 0; CT1 < 10; CT1++) { RS[CT1] = null; }
                AAAOLD = MKST.OJ;
                MessageBox.Show("[" + AAAOLD[0].ToString() + "][" + AAAOLD[1].ToString() + "][" + AAAOLD[2].ToString() + "]");
                WS = AAAOLD[1].ToString();
                RS[GI] = WS; PS = WS + "×" + AAAOLD[2].ToString(); FG2 = 1;
                while (FG2 == 1)
                {
                    MessageBox.Show("sm20[" + AAAOLD[0].ToString() + "][" + AAAOLD[1].ToString() + "][" + AAAOLD[2].ToString() + "]");
                    FG2 = CDBA.DBF("部品構成", "部番 = '" + WS + "'", "部番,部品", PM10T);
                    PM20OLD = MKST.OJ;
                    MessageBox.Show("pm20[" + PM20OLD[0].ToString() + "][" + PM20OLD[1].ToString() + "][" + PM20OLD[2].ToString() + "]");
                    MessageBox.Show("sm20[" + AAAOLD[0].ToString() + "][" + AAAOLD[1].ToString() + "][" + AAAOLD[2].ToString() + "]");
                    if (FG2 == 1)
                    {
                        //PM20OLD = MKST.OJ;
                        PS = PS + PM20OLD[1].ToString() + "×" + PM20OLD[2].ToString();
                        WS = PM20OLD[1].ToString();
                    }
                    else
                    {
                        listBox1.Items.Add(PS);
                        break;
                    }
                }
                MessageBox.Show("next[" + AAAOLD[0].ToString() + "][" + AAAOLD[1].ToString() + "][" + AAAOLD[2].ToString() + "]");
                FG1 = CDBA.DBF("製品構成", "品番 = '" + AAAOLD[0].ToString() + "' and 部番 > '" + AAAOLD[1].ToString() + "'", "品番,部番", AAAT);
            }
        }
でDBFを使うとAAAOLDの中身がPM20OLDにOJをコピーするとPM20OLDの中身と同じになってしまいます。AAAOLDの中身とPM20OLDは別のものでなければなりません。どうしたら回避できるでしょうか?ご教授お願いいたします。

引用返信 編集キー/
■51804 / inTopicNo.2)  Re[1]: objectの内容が勝手に変わってしまいます
□投稿者/ よねKEN (547回)-(2010/07/20(Tue) 17:16:01)
よねKEN さんの Web サイト
> でDBFを使うとAAAOLDの中身がPM20OLDにOJをコピーするとPM20OLDの中身と同じになってしまいます。
> AAAOLDの中身とPM20OLDは別のものでなければなりません。
> どうしたら回避できるでしょうか?ご教授お願いいたします。

「AAAOLD = MKST.OJ;」というコードは、配列の要素のコピーではなく、配列の参照のコピーです。
AAAOLDとMKST.OJが指す配列は同じ配列です。

配列は参照型ですので、たとえば整数を代入するようにはなりません。
参照型と値型の違いについて調べてみてください。

現状のコードで最小限の修正で済ませるなら、以下の2つの方法が考えられます。

(1) DBFメソッドの先頭で 「MKST.OJ = new Object[200];」と書いてOJの配列インスタンスを初期化する
(2) 「AAAOLD = MKST.OJ;」の部分をArray.Copyメソッドを使った配列のコピー処理に書き換える

上記のどちらも応急処置的な方法であり、まったくお勧めではありません。

根本的な対応としては、DBFメソッドでグローバルな配列に結果をセットするのではなく、
そもそも結果の配列自体を返せばよいと思います。

今は、処理結果の成否を0 or 1で返しているようですが、
この戻り値として配列を返せばよい、という意味です。
処理が失敗したときはnullを返すようにすれば成否の判断もできます。

あるいはどうしても成否を表すステータスを戻り値として返したいなら、
最終のパラメータに配列インスタンスを受け取るパラメータを用意し、
その配列に対して各要素をセットすればよいです。


引用返信 編集キー/
■51807 / inTopicNo.3)  Re[2]: objectの内容が勝手に変わってしまいます
□投稿者/ 裕猫 (147回)-(2010/07/20(Tue) 17:47:31)
No51804 (よねKEN さん) に返信
> 「AAAOLD = MKST.OJ;」というコードは、配列の要素のコピーではなく、配列の参照のコピーです。
> AAAOLDとMKST.OJが指す配列は同じ配列です。
>
> 配列は参照型ですので、たとえば整数を代入するようにはなりません。
> 参照型と値型の違いについて調べてみてください。
返信ありがとうございます。配列は参照型なんだ。知りませんでした。
>
> 根本的な対応としては、DBFメソッドでグローバルな配列に結果をセットするのではなく、
> そもそも結果の配列自体を返せばよいと思います。
この方法にプログラムを修正しようと思います。

> 今は、処理結果の成否を0 or 1で返しているようですが、
> この戻り値として配列を返せばよい、という意味です。
> 処理が失敗したときはnullを返すようにすれば成否の判断もできます。
ここは作ってから失敗したなと思ってました。なのでアドバイス通り配列自体を返すように作り直します。
ありがとうございました。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -