1.概要
例えば下記のようなファイルを削除する関数があります。
private bool FileDelete(string filePass) { try { System.IO.File.Delete(filePass); return true; } catch (Exception ex) { Console.WriteLine(ex.GetType().FullName + ":" + ex.Message); return false; } }
削除が成功したら【true】、削除が失敗したら【false】
を戻り値として返します。
【true】だった場合は問題にならないのですが
【false】だった場合、何故失敗したのか?がわかりません。
わからないということは原因不明のエラーに悩まされてしまうことになります。
2.参照渡しを使う方法
【C#】において引数は【値渡し】であることが一般的です。
一般的ということは例外も存在するということで
これが【参照渡し】になります。
【参照渡し】の方法としては【ref】と【out】が存在します(【in】は省略)
違いを簡単に説明すると
上記のような感じかと思います。
今回は戻り値を複数取得したいだけなので【out】を使います。
先程のファイルを削除する関数を下記のように変更しました。
private void FileDelete(string filePass, out bool argRes, out string argStr) { try { System.IO.File.Delete(filePass); argRes = true; argStr = ""; } catch (Exception ex) { argRes = false; argStr = ex.GetType().FullName + ":" + ex.Message; } }
呼び出し元には下記のとおり記述します。
bool res; string str; FileDelete(@"C:\test\test.txt", out res, out str);
結果としては
res = false str = System.IO.IOException:別のプロセスで使用されているため、プロセスはファイル 'C:\\test\\test.txt' にアクセスできません。
となりました。
※ファイル使用中のエラーを模擬
3.Tuple型を使う方法
C# 6までは【参照渡し】が戻り値を複数返す唯一の方法でしたが
C# 7から【Tuple型】が追加されました。
【参照渡し】で問題だった、非同期メソッドでは使用できないという問題も
【Tuple型】では解消されています。
では、例によってファイルを削除する関数を下記のように変更しました。
private ValueTuple<bool, string> FileDelete(string filePass) { ValueTuple<bool, string> result; try { System.IO.File.Delete(filePass); result.Item1 = true; result.Item2 = ""; } catch (Exception ex) { result.Item1 = false; result.Item2 = ex.GetType().FullName + ":" + ex.Message; } return result; }
呼び出し元には下記のとおり記述します。
var res = FileDelete(@"C:\test\test.txt");
結果ですが
result.Item1 = false result.Item2 = System.IO.IOException:別のプロセスで使用されているため、プロセスはファイル 'C:\\test\\test.txt' にアクセスできません。
となりました。
4.使ってみた感想
呼び出し元で変数を宣言する必要がない分
【Tuple型】を使う方がすっきりしたといったイメージです。
ただ、慣れてないので今のところ使い勝手は悪いです・・・
ちなみに開発環境が【Visual Studio 2015】だったので
【System.ValueTuple】をNugetからインストールする必要がありました。
これをしないと構文エラーが出てしまいます。