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

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

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

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

Q&A

解決済

1回答

1608閲覧

【C#】電卓作成:インスタンス化で無限ループになってしまう

Mr.sijimi

総合スコア21

C#

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

0グッド

0クリップ

投稿2020/07/21 02:33

編集2020/07/21 04:34

前提・実現したいこと

C#でクリック操作でできる電卓を作成してますが
Mainwindow処理の「var IniEvent = new Initialize()」で
無限ループになってしまい処理が進みません。

該当のソースコード

C#

1namespace Calculator 2{ 3 public partial class MainWindow : Window 4 { 5 /// <summary> 6 /// コンストラクタ 7 /// </summary> 8 public MainWindow() 9 { 10 InitializeComponent(); 11 12 //イベント初期化 13 var IniEvent = new Initialize(); 14 IniEvent.InitializeEvent(); 15 } 16 } 17}

C#

1namespace Calculator 2{ 3 public partial class Initialize : MainWindow 4 { 5 /// <summary> 6 /// イベント初期化 7 /// </summary> 8 public void InitializeEvent() 9 { 10 //rootGridは以下のコントロールを探す 11 foreach (var ctrl in LogicalTreeHelper.GetChildren(rootGrid)) 12 { 13 //ボタン以外は無視 14 if (!(ctrl is Button)) 15 { 16 continue; 17 } 18 19 //ボタンがクリックされたときの処理登録 20 (ctrl as Button).Click += (sender, e) => 21 { 22 string inKey = (sender as Button).Content.ToString(); 23 switch (inKey) 24 { 25 //クリア 26 case "AC": 27 formula.Text = "0"; 28 break; 29 case "=": 30 if (formula.Text == MessageList.CFNM0001) 31 { 32 formula.Text = "0"; 33 } 34 else 35 { 36 //計算結果表示 37 var Calc = new CalculateProcess(); 38 formula.Text = Calc.Calculator(formula.Text); 39 } 40 break; 41 default: 42 if (formula.Text.Length >= ItemProperty.FormulaMax) 43 { 44 break; 45 } 46 else if (formula.Text == "0" && (inKey != "/" && inKey != "*" && inKey != "-" && inKey != "+")) 47 { 48 formula.Text = inKey; 49 } 50 else if (formula.Text == MessageList.CFNM0001) 51 { 52 //0が表示されていて数字が入力されたらその値を設定 53 formula.Text = inKey; 54 } 55 else 56 { 57 //入力された値を式に追加 58 formula.Text += inKey; 59 } 60 break; 61 } 62 }; 63 } 64 } 65 } 66}

追記

C#

1namespace Calculator 2{ 3 public partial class CalculateProcess : MainWindow 4 { 5 /// <summary> 6 /// 計算実行 7 /// </summary> 8 /// <param name="formula">計算式</param> 9 /// <returns>計算結果</returns> 10 public string Calculator(string formula) 11 { 12 try 13 { 14 var p = new Process(); 15 16 // システムフォルダの取得 17 string systemFolder = Environment.GetFolderPath(Environment.SpecialFolder.System); 18 // PowerShellのフルパスを組立 19 string powerShellFullPath = System.IO.Path.Combine(systemFolder, @"WindowsPowerShell\v1.0\powershell.exe"); 20 21 // 実行ファイル 22 p.StartInfo.FileName = powerShellFullPath; 23 // パラメータ(計算式) 24 p.StartInfo.Arguments = "-Command " + formula; 25 26 // 標準入力リダイレクトしない 27 p.StartInfo.RedirectStandardInput = false; 28 // 標準入力リダイレクトする 29 p.StartInfo.RedirectStandardOutput = true; 30 31 32 // シェル機能使用しない 33 p.StartInfo.UseShellExecute = false; 34 // ウィンドウ開かない 35 p.StartInfo.CreateNoWindow = true; 36 37 // 実行 38 p.Start(); 39 // 結果を一行読む 40 string calcResult = p.StandardOutput.ReadLine(); 41 p.WaitForExit(); 42 p.Close(); 43 44 if (string.IsNullOrEmpty(calcResult)) 45 { 46 // 計算結果無し(計算失敗) 47 return MessageList.CFNM0001; 48 } 49 else 50 { 51 // 計算結果を返す 52 return calcResult; 53 } 54 } 55 catch 56 { 57 return MessageList.CFNM0001; 58 } 59 } 60 61 } 62}

試したこと

「インスタンス化 無限ループ」や、「Main 無限ループ」などで調べてみましたが出てこず、原因がわかりません。

なぜ、無限ループになっているのでしょうか?
また、どのように改善をしたらよろしいのでしょうか?
よろしければ教えてください

補足情報(FW/ツールのバージョンなど)

Windows10 Pro 64bit
Visual Studio 2015

他必要な情報がありましたらご教示ください。

解決方法(済)

C#

1namespace Calculator 2{ 3 public partial class Initialize 4 { 5 /// <summary> 6 /// イベント初期化 7 /// </summary> 8 public void InitializeEvent(MainWindow w) 9 { 10 //rootGridは以下のコントロールを探す 11 foreach (var ctrl in LogicalTreeHelper.GetChildren(w.rootGrid)) 12 { 13 //ボタン以外は無視 14 if (!(ctrl is Button)) 15 { 16 continue; 17 } 18 19 //ボタンがクリックされたときの処理登録 20 (ctrl as Button).Click += (sender, e) => 21 { 22 string inKey = (sender as Button).Content.ToString(); 23 switch (inKey) 24 { 25 //クリア 26 case "AC": 27 w.formula.Text = "0"; 28 break; 29 case "=": 30 if (w.formula.Text == MessageList.CFNM0001) 31 { 32 w.formula.Text = "0"; 33 } 34 else 35 { 36 //計算結果表示 37 var Calc = new CalculateProcess(); 38 w.formula.Text = Calc.Calculator(w.formula.Text); 39 } 40 break; 41 default: 42 if (w.formula.Text.Length >= ItemProperty.FormulaMax) 43 { 44 break; 45 } 46 else if (w.formula.Text == "0" && (inKey != "/" && inKey != "*" && inKey != "-" && inKey != "+")) 47 { 48 w.formula.Text = inKey; 49 } 50 else if (w.formula.Text == MessageList.CFNM0001) 51 { 52 //0が表示されていて数字が入力されたらその値を設定 53 w.formula.Text = inKey; 54 } 55 else 56 { 57 //入力された値を式に追加 58 w.formula.Text += inKey; 59 } 60 break; 61 } 62 }; 63 } 64 } 65 } 66} 67

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

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

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

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

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

y_waiwai

2020/07/21 02:38

どこが無限ループになるんでしょう
Mr.sijimi

2020/07/21 02:41

分かりにくい文面になってしまい申し訳ございません。 ループ箇所はMainWindow()内のインスタンス箇所となっております。 InitializeEvent()を呼び出すところまでいかずループしている状態です。
退会済みユーザー

退会済みユーザー

2020/07/21 02:48 編集

Initializeクラスのコンストラクタで何か処理を行っていますか? InitializeEventまで到達していないという事は、それ以前の処理に問題があると思いますが
y_waiwai

2020/07/21 02:47

なら、Initializeクラスの全文を提示してもらわないとしようがないですが
Mr.sijimi

2020/07/21 02:50 編集

すぐに修正いたします。 また、Initializeクラス内で呼び出している別項目のメソッドもあるのでそちらも念のため記載に追記しておきます。
Zuishin

2020/07/21 02:56 編集

> InitializeEvent()を呼び出すところまでいかずループしている状態です。 そこまで行ってないならそこは関係ないので見ても仕方ありませんが。 new Initialize() で止まっているのか、それとも InitializeComponent() で止まっているのか、それともそれより前に止まっているのかをまず確定し、止まった位置を判断した根拠を掲載するところから始めてはどうでしょう。
Mr.sijimi

2020/07/21 02:57

Zuishin様 ご指摘ありがとうございます。 質問内容を修正させていただきます。
Zuishin

2020/07/21 03:08

別のところで止まってないですか? こちらではちゃんと確かめてないので、ブレークポイントとステップ実行を使って、どこで止まっているのか確かめてください。 勘ですが、なぜか MainWindow を継承しているクラスが再帰的に初期化しようとしているんじゃないかと思います。
guest

回答1

0

ベストアンサー

public partial class Initialize : MainWindow

MainWindowを継承してるなら、こいつのクラス生成時にはMainWindowのコンストラクタも呼ばれてしまうので、そりゃ無限ループとなってしまいます。

こいつのクラス設計を考え直す必要がありますね

投稿2020/07/21 03:01

編集2020/07/21 03:10
y_waiwai

総合スコア88042

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

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

Zuishin

2020/07/21 03:13

このソースだけ見ると、サブクラスの初期化はクリックベントハンドラの中で行われているので呼ばれていないはずなんですが。 まあ多かれ少なかれその辺りに原因があるんでしょうけど。
Zuishin

2020/07/21 03:14

いや、違う。見落としていました。そっちのクラスも継承してたんですね。
Mr.sijimi

2020/07/21 04:06

ありがとうございます。 継承する際のインスタンス関係を見落としてました。 継承とインスタンスの関係をもう少し調べてみます。
len_souko

2020/07/21 04:16

MainWindowを継承して作るというクラス設計が問題です Windowクラスを継承して作るべきです 何か固有の機能をすべてに持たせたいのなら、Windowを継承したBaseWindowみたいなクラスを定義し、それを継承して他のウィンドウクラスを設計すべきです
Mr.sijimi

2020/07/21 04:31

InitializeクラスでMainWindowを継承せずにInitializeEvent()の引数でMainWindowを参照したらループから脱出できました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問