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

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

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

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

Q&A

解決済

3回答

438閲覧

コンソールアプリケーション内の独自コマンド作成について

yushistr

総合スコア12

C#

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

0グッド

0クリップ

投稿2018/03/21 01:33

現在DiscordのBOTをC#で開発している者です。
BOTを開発するにあたってBOTの挙動をある程度起動中に変更できるように
Console.ReadLine() で待機させてBOTアプリケーション内の独自コマンドを受け付けるような実装をしているのですが、
デバッグで使用する早期の必要性からコードの見栄えより機能の実現を優先したため、
単純にswitch文で分岐させてcaseには対応コマンドをstringでそのまま実装しているのでコードがかなり酷い状態になっています。(機能自体は正常に動いています)
開発のためにDiscord APIの英語コミュニティにも通っているのですが、案の定「そのswitch文酷すぎワロタ」(意訳)と言われてしまい・・
一応ここに質問する前にググったのですが、意外とアプリケーション独自のCUIコマンドの実装を紹介しているところがないんですね。。
皆さんならどのように独自のCUIコマンドを実装するのでしょうか?

仕様としては
・Console.ReadLine()でコマンドの入力を受け付ける
・何も入力しなかったり誤ったコマンドを入力しEnterすると画面のみ更新される
・対応するコマンドを入力するとそのコマンドに対応した処理を実行する

が満たせれば十分です。
よろしくお願いします。

以下現状の酷いコードです。。。

C#

1public static async Task StartConsole() 2 { 3 try 4 { 5 while (true) 6 { 7 string input; 8 input = Console.ReadLine(); 9 string savewindowtimes_id; 10 switch (input) 11 { 12 default: 13 Program.isShowLog = false; 14 Console.Clear(); 15 VersionHeader(); 16 Console.WriteLine(SystemMessageDefine.CommanderModeGuide_JP); 17 break; 18 19 case "showlog": 20 Console.Clear(); 21 VersionHeader(); 22 Program.isShowLog = true; 23 Console.WriteLine(SystemMessageDefine.LogShowMode_JP); 24 Console.WriteLine(SystemMessageDefine.CommandAccepting_JP); 25 break; 26 case "quit": 27 Console.Clear(); 28 VersionHeader(); 29 Environment.Exit(0); 30 (以下延々と続く)

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

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

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

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

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

guest

回答3

0

ベストアンサー

コマンドごとに関数を用意して、コマンド(文字列)と関数ポインタのマップを作ると見通しが良くなるように思います。

1)コンソールからコマンドを入力する
2)入力された文字列が、マップのKeyに含まれていなければ
defaultの関数を呼び出す。 (if)
マップのkeyに含まれていれば、
マップから関数ポインタを得て実行する。(else)

というのがメインループの中身。

ループの前にマップを作るコードが入り、コードの後半はそれぞれのコマンドで実行する内容を関数として記述したものを列挙します。

こうしておけば、コマンドを追加するのは関数の追加とマップの修正だけで済みますし、1つのコマンドの機能を修正する際に変更する箇所が1つの関数だけになるのでコードの管理が楽です。

投稿2018/03/21 02:03

coco_bauer

総合スコア6915

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

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

yushistr

2018/03/21 10:08

ありがとうございます。参考にさせていただきます。
guest

0

csharp

1using System; 2using System.Collections.Generic; 3 4namespace Wandbox 5{ 6 class Program 7 { 8 static void Main(string[] args) 9 { 10 var table = new Dictionary<string, Action<string, string>>(); 11 // コマンドの追加 12 table["test"] = (user, msg) => {Console.WriteLine($"{user}: {msg}");}; 13 // コマンドを呼び出してみる 14 table["test"]("Tom", "Hello"); 15 } 16 } 17} 18

こんな感じ

投稿2018/03/21 03:42

asm

総合スコア15147

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

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

yushistr

2018/03/21 10:10

Dictionaryでの管理は自分では思いつきませんでした。こちらも参考にさせていただきます。
guest

0

プログラムを見やすくする、というのは、いかに分割するか、に尽きます

現状ではtryがあってwhileがあってswitchがあって、と理解しようとするとなかなか骨が折れます。
そこで、まずはswitch 文を丸々べつ関数に切り出してしまいます(文字列(input)を引数とする関数となりますか)。
そうすると、StartConsole関数は、文字列入力してなんかさせる関数に渡すだけの関数、とひと目でスッキリ理解できるようになります
なんかさせる関数、の方でも、caseが多くなったりその中の処理がややこしくて長文になったりすると、これまたややこしい関数になってしまうので、その処理もなんかする関数にして切り出していきます。

こうしていくと、処理を考えるにしても、余計な細かいことまでアタマに入れなくて済むので楽になります

当然のことながら、考えなしに関数増やしてしまうと、これまたややこしくなってしまいますがw

投稿2018/03/21 02:56

y_waiwai

総合スコア87774

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

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

yushistr

2018/03/21 10:09

こちらも設計の参考にさせていただきます。どうもです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問