🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C#

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

Q&A

解決済

2回答

821閲覧

同じようなことを繰り返す処理の記述が冗長になってしまう

moshi

総合スコア90

C#

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

0グッド

0クリップ

投稿2019/12/11 02:52

前提・実現したいこと

Treeviewで指定のパス(/opt/test/001/9991/20191210/093011/test.csv)を表示するという機能を作成していたのですが、その処理を記述するにあたって同じようなことを繰り返しているためうまくまとめたいです。
同じことを繰り返していることには気づいたのですが、for文などで記述を短くしようとしてみてもこれをどうすれば短くできるのかがわかりませんでした。
どうすればうまく記述できるでしょうか?

該当のソースコード

C#

1// ノード作成 2List<TreeNode> treeList = new List<TreeNode>(); 3 4foreach (string dir in dirNameList) 5{ 6 TreeNode tn = new TreeNode(dir); 7 8 testService ts = new testService(); 9 List<DirectoryInfo> subDirList = new List<DirectoryInfo>(); 10 subDirList = ts.GetDir(GetFilePath(path, dir)); 11 12 foreach (DirectoryInfo di in subDirList) 13 { 14 TreeNode child = new TreeNode(di.Name); 15 TreeNode tn2 = new TreeNode(child.Text); 16 List<DirectoryInfo> subDirList2 = new List<DirectoryInfo>(); 17 subDirList2 = ts.GetDir(GetFilePath( 18 GetFilePath(path, dir), 19 di.Name)); 20 foreach (DirectoryInfo di2 in subDirList2) 21 { 22 TreeNode child2 = new TreeNode(di2.Name); 23 TreeNode tn3 = new TreeNode(child2.Text); 24 List<DirectoryInfo> subDirList3 = new List<DirectoryInfo>(); 25 subDirList3 = ts.GetDir(GetFilePath( 26 GetFilePath( 27 GetFilePath( 28 path, dir), di.Name), 29 di2.Name)); 30 foreach (DirectoryInfo di3 in subDirList3) 31 { 32 TreeNode child3 = new TreeNode(di3.Name); 33 TreeNode tn4 = new TreeNode(child3.Text); 34 List<DirectoryInfo> subDirList4 = new List<DirectoryInfo>(); 35 subDirList4 = ts.GetDir(GetFilePath( 36 GetFilePath( 37 GetFilePath( 38 GetFilePath( 39 path, dir), di.Name), di2.Name), 40 di3.Name)); 41 foreach (DirectoryInfo di4 in subDirList4) 42 { 43 TreeNode child4 = new TreeNode(di4.Name); 44 TreeNode tn5 = new TreeNode(child3.Text); 45 List<DirectoryInfo> subDirList5 = new List<DirectoryInfo>(); 46 subDirList5 = ts.GetDir(GetFilePath( 47 GetFilePath( 48 GetFilePath( 49 GetFilePath( 50 GetFilePath( 51 path, dir), di.Name), di2.Name), di3.Name), 52 di4.Name)); 53 foreach (DirectoryInfo di5 in subDirList5) 54 { 55 TreeNode child5 = new TreeNode(di5.Name); 56 tn5.Nodes.Add(child5); 57 } 58 tn4.Nodes.Add(tn5); 59 } 60 tn3.Nodes.Add(tn4); 61 } 62 tn2.Nodes.Add(tn3); 63 } 64 tn.Nodes.Add(tn2); 65 } 66 treeList.Add(tn); 67} 68

C#

1// ディレクトリ情報を取得 2public List<DirectoryInfo> GetDir(string path) 3{ 4 List<DirectoryInfo> ret = new List<DirectoryInfo>(); 5 6 // 指定フォルダ以下のサブフォルダをすべて取得する 7 DirectoryInfo di = new System.IO.DirectoryInfo(path); 8 DirectoryInfo[] subFolders = 9 di.GetDirectories("*", System.IO.SearchOption.TopDirectoryOnly); 10 11 ret.AddRange(subFolders); 12 13 return ret; 14}

C#

1// ファイルパス結合 2public static string GetFilePath(string basePath, string addPath) 3{ 4 string ret = ""; 5 string path = "/opt/test/"; 6 return ret = Path.Combine(path, basePath, addPath); 7}

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

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

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

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

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

guest

回答2

0

再帰呼び出しを使ってください。

あと

C#

1List<DirectoryInfo> subDirList = new List<DirectoryInfo>(); 2subDirList = ts.GetDir();

のような無意味な記述が散見されるので修正した方がよいかと思います(このような初期化は不要)

投稿2019/12/11 03:03

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

moshi

2019/12/12 02:16

アドバイスありがとうございます。 再帰呼び出しの存在を知らなかったので助かりました。 二回newしてしまっているところについても修正しました。ありがとうございました。
guest

0

ベストアンサー

ツリー構造を扱う場合は「再帰呼び出し(Recursive Call)」を使うと便利です。

ノードそれぞれが同じ内容であれば同一のメソッドで処理できるよね、というイメージです。

csharp

1TreeNode RecursiveCreateTreeNodeFromDirectory(DirectoryInfo dirInfo) 2{ 3 TreeNode treeNode = new TreeNode(dirInfo.FullName); 4 var subDirectories = dirInfo.GetDirectories("*", System.IO.SearchOption.TopDirectoryOnly); 5 foreach (var subDir in subDirectories) 6 { 7 var subNode = RecursiveCreateTreeNodeFromDirectory(subDir); 8 treeNode.Nodes.Add(subNode); 9 } 10 11 return treeNode; 12}

投稿2019/12/11 07:47

編集2019/12/12 02:45
tor4kichi

総合スコア769

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

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

moshi

2019/12/12 02:15

再帰呼び出しについて具体例を提示していただきありがとうございました。 For文でなくこんな風に繰り返すやり方があったんですね。助かりました。
Zuishin

2019/12/12 02:44

ディレクトリのような木構造を探索するのは再帰が簡単ですが、なるべくキューやスタックをヒープに作るのが望ましいです。 https://ja.wikipedia.org/wiki/%E5%B9%85%E5%84%AA%E5%85%88%E6%8E%A2%E7%B4%A2 https://ja.wikipedia.org/wiki/%E6%B7%B1%E3%81%95%E5%84%AA%E5%85%88%E6%8E%A2%E7%B4%A2 C# の場合 x64 以外では末尾再帰最適化をしないので、再帰を使うとスタックオーバーフローが発生する恐れがあります。(質問サイトの名前にもなっているくらい悩まされる人の多いエラーです) https://yone64.wordpress.com/2011/03/06/c%E3%81%A8%E6%9C%AB%E5%B0%BE%E5%86%8D%E5%B8%B0%E3%81%A8%E6%9C%AB%E5%B0%BE%E6%9C%80%E9%81%A9%E5%8C%96/ この回答のコードの場合は、末尾再帰ではないので、x64 でも最適化されません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問