質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

1回答

693閲覧

List<PointF> で個別に宣言した変数の値が同じになってしまう!?

byori

総合スコア72

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2020/09/25 06:54

フォームに線を引いた時の x, y の値を記憶させておくために

public List<PointF> linePoints1 = new List<PointF>(); public List<PointF> linePoints2 = new List<PointF>(); public List<PointF> linePoints3 = new List<PointF>();

と宣言しています。
でも下記のコードを実行すると全部同じ値になります。

コードの説明
下記の lineDrawfrm[3] は、Form です。3枚あってonDrawing = true の時、線を引けます。同時に1枚だけ。
線は、lineDrawfrmのフォームに引くのではなく別のフォームに書きます。
この時、lineDrawfrm[0]は、linePoints1、lineDrawfrm[1]は、linePoints2、lineDrawfrm[2]は、linePoints3
の各線の軌跡を保持しています。50個位の Point[x=0, y=0]・・・ みたいな値。

問題は、linePoints1.Add((PointF)m_position);した時、同時にlinePoints2、linePoints3にも同じ値がセットされます。
下記の通りグローバルな変数ですが独立して宣言しています。
linePoints1 に値をセットしたとき linePoints2、linePoints3 にも同じ値がセットされる理由がわかりません。
どうしたら回避できますか?
(下記のコードは一部割愛しています。MouseMove内のすべてが必要なら教えてください。)

VS2015 WinForm C# Windows10

C#

1 public List<PointF> linePoints1 = new List<PointF>(); 2 public List<PointF> linePoints2 = new List<PointF>(); 3 public List<PointF> linePoints3 = new List<PointF>(); 4 Point m_position; 5 6 : 7 8 private void m_frmdummy_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e) 9 { 10 if (e.Button == MouseButtons.Left && lineDrawfrm != null) 11 { 12 if (lineDrawfrm[nDrawingLineNumber - 1] == null) 13 return; 14 15 if (lineDrawfrm[nDrawingLineNumber - 1].drawing.onDrawing) 16 { 17 18 : 19 20 // 線を引いている 21 Point p = m_frmdummy.PointToClient(Cursor.Position); 22 23 Pen pen = new Pen(lineColor, 10); 24 Brush brsh = new SolidBrush(lineColor); 25 g.DrawLine(pen, m_position, p); 26 g.FillEllipse(brsh, p.X - pen.Width / 2, p.Y - pen.Width / 2, pen.Width, pen.Width); 27 28 m_position = p; 29 pen.Dispose(); 30 31 if (nDrawingLineNumber == 1) 32 linePoints1.Add((PointF)m_position); <- 問題はここ 33 if (nDrawingLineNumber == 2) 34 linePoints2.Add((PointF)m_position); 35 if (nDrawingLineNumber == 3) 36 linePoints3.Add((PointF)m_position); 37 38 : 39 }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/09/25 07:11

m_frmdummy とか定義不明のようですけど? 問題を再現するのに不要なコードはどんどん削っていって原因がどこにあるのか切り分けしていってはいかがですか。ふつうはその過程で自己解決できると思います。それが質問者さんも望む解決法ではないのでしょうか。
退会済みユーザー

退会済みユーザー

2020/09/25 07:22

同じ値がセットされるということはセットされる場所を通過している筈なので、デバッグでステップ実行しつつ変数の値を確認してみればよいのではないでしょうか。技術的に判らない所はアドバイスは出来ますが、デバッグは基本的に地道な作業なので自分でやりましょう。
byori

2020/09/25 07:23

そうですね。 今、打つ手がわからないので試してみます。
byori

2020/09/27 04:44

ちょっと時間がかかりましたが、初期化の問題のようでした。 以下のように初期化していて同じ1つの値を3つ(linePoints1, linePoints2, linePoints3)に転記していました。この処理を通った時、現象を確認し、ここをコメントすると起きませんでした。 一度このような初期化をするとその後、3つが同じ扱いになってしまうのですね。 理由まではわかりませんが・・・ List<PointF> lpos = new List<PointF>();    : linePoints1 = LinePosforClear1 = lpos; linePoints2 = LinePosforClear2 = lpos; linePoints3 = LinePosforClear3 = lpos;
guest

回答1

0

自己解決

ちょっと時間がかかりましたが、初期化の問題のようでした。

以下のように初期化していて同じ1つの値を3つ(linePoints1, linePoints2, linePoints3)に転記していました。この処理を通った時、現象を確認し、ここをコメントすると起きませんでした。

一度このような初期化をするとその後、3つが同じ扱いになってしまうのですね。
理由まではわかりませんが・・・

C#

1List<PointF> lpos = new List<PointF>(); 2   : 3linePoints1 = LinePosforClear1 = lpos; 4linePoints2 = LinePosforClear2 = lpos; 5linePoints3 = LinePosforClear3 = lpos;

ありがとうございました。

投稿2020/09/27 04:47

byori

総合スコア72

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/09/27 05:41 編集

参照型は、インスタンスを他の変数に代入しても同じインスタンスを指します。値型、構造体の場合はコピーされます。
byori

2020/09/27 06:07

そうなんですね。 以前、C++ の時のポインタ変数だったのですね。 new すれば、すべて独立型と思って何ら疑いがありませんでした。 勉強になります。
退会済みユーザー

退会済みユーザー

2020/09/27 06:15

全部 new で作成してるなら、その時点では独立している筈です。 lposで上書きした事によって、全部同じインスタンス(lpos)を指してしまってますね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問