R.Tanaka.Ichiro's Blog

主にC# な話題です

目次

Blog 利用状況

ニュース

値の出力はイコールの左辺に

全ての値の出力はイコールの左辺に持って来られたら

素敵だし爽やか

と、いつも思っています。

例えば、お馴染みの以下の C# のコードを見て下さい。


int i = 0;
if (int.TryParse("5", out i)) return i;


僕は、この out が、どうも馴染めません。
なので、場合によっては、左辺にまとめるために、わざわざ型を作っちゃうこともあります。


class 戻り値 {
  public int 値 = 0;
  public bool 変換OK = false;
}


で、以下のような感じで使う・・・


戻り値 r = IntTryParse("5");
if (r.変換OK) return r.値;


でも、こう書くのが本当に良いかと言うと、結局 2 行に分かれてしまう訳だから、out を使う方が使いやすいようにも思いますね。

まあ、どうでも良いという気もしますけど、毎度思うので、皆さんはどう思っているのかな?、と気になるところだったりします。

投稿日時 : 2007年4月20日 10:37

Feedback

# re: 値の出力はイコールの左辺に 2007/04/20 10:51 じゃんぬねっと

ValueType.TryParse メソッドの場合は、名前からして別に問題ないと思います。
むしろ、is の結果と Parse の結果をひとまとめにする方が違和感があります。

それをするくらいなら、TryParse 後に Parse した方がまだマシでしょう。

# re: 値の出力はイコールの左辺に 2007/04/20 11:11 通りすがり

私の場合、変換した結果と成否を逆にしてもよいのではと思ったことがあります。
Rさんと同じ仕様を書くなら次のようになります。

bool isSuccess;
int result = int.TryParse("5", out isSuccess);
if (isSuccess) return result;

これだと素敵だし爽やかに近づきません?
けどやっぱり TryParse は今の方がよいと思っています。
失敗した時の値が気持ち悪いのでw

ただ、もし TryParseDefault みたいなメソッドだとそれでもいいかななんて思いません?(out success はオーバーロードで省略可能で)

int result = int.TryParseDefault("5", 0, out success);

#通りすがってない...

# re: 値の出力はイコールの左辺に 2007/04/20 11:27 シャノン

> is の結果と Parse の結果をひとまとめにする方が違和感があります。

激しく同意。

# re: 値の出力はイコールの左辺に 2007/04/20 12:06 Hirotow

正規表現なんかはこの形式ですが、俄然まともに例外処理をしようとすると1行では書けません。

# re: 値の出力はイコールの左辺に 2007/04/20 12:06 オノデラ

個人的には Try メソッドがほしかったりもします。

string s = XXX
if (int.Try(s))
{
// なにか
}

# re: 値の出力はイコールの左辺に 2007/04/20 12:14 オノデラ

Try っていう名前じゃ意味不明だ。orz

第2引数のない TryParse のほうが正しいかも。(ほんとの意味での Parse を Try(試す))

string s = XXX
if (int.TryParse(s))
{
// なにか
}

とりあえず値はいらないから変換できるか試したいっていうときに。

# re: 値の出力はイコールの左辺に 2007/04/20 13:06 とりこびと

Parseできるかどうかであればメソッド名はCanParseじゃだめですか?

string s = XXX;
if (int.CanParse(s))
{
 int i = int.Parse(s);
}

# これならどうかなぁ? 2007/04/20 21:10 へぼろっぱぁ

これならどうかなぁ?

# これならどうかなぁ? 2007/04/20 21:13 へぼろっぱぁ

これならどうかなぁ?

# re: 値の出力はイコールの左辺に 2007/04/21 19:18 siokoshou

はじめまして。
TryParseって2つの値を返してくるメソッドと考えるときれいに見えてきませんか?
C言語だとポインタを使って多値を返したりしますが、C#だとoutで言語がきっちりとこれをサポートしています。呼ぶ方、呼ばれる方のどちらでもoutと明示するので、どちらを見ても多値を返すことがはっきりわかります。
また、返し忘れたりするとコンパイルエラーになります。
こう考えると、すごくきれいに見えてきませんか?

私はoutって素敵だし爽やかだと思いますよ。

# re: 値の出力はイコールの左辺に 2007/04/21 19:58 R・田中一郎

じゃんぬねっと さん

>ValueType.TryParse メソッドの場合は、名前からして別に問題ないと思います。

サンプルが悪かったと反省。

>それをするくらいなら、TryParse 後に Parse した方がまだマシでしょう。

あっ、確かに、その方が良いですね。
どなたか、サンプル書いてましたね。

--------------------------------------------------------
通りすがり さん

>私の場合、変換した結果と成否を逆にしてもよいのではと思ったことがあります。

うーん、やっぱり TryParse をサンプルにしたのは間違いだったのかな。
でも、言わんとすることはわかります。

>けどやっぱり TryParse は今の方がよいと思っています。

ですね^^;

>ただ、もし TryParseDefault みたいなメソッドだとそれでもいいかななんて思いません?

思います、ってか似たようなメソッド作って使いまわしてますw

>#通りすがってない...

コテハンなの?w

--------------------------------------------------------
シャノン さん

>激しく同意。

シャノンさんは、out に違和感感じない人ですか?

--------------------------------------------------------
Hirotow さん

>正規表現なんかはこの形式ですが、俄然まともに例外処理をしようとすると1行では書け

まあ、2行でもいいんですけどね。
何より out が嫌。

--------------------------------------------------------
オノデラ さん

第2引数のない TryParse のほうが正しいかも。(ほんとの意味での Parse を Try(試す))

僕もそう思いました。
なるほど、一度に受け取りたい人には out で、ということでいい気もしますね。

--------------------------------------------------------
とりこびと さん

>Parseできるかどうかであればメソッド名はCanParseじゃだめですか?

あ、確かに、その方が良いですね。

#さすが、お笑い同盟(関係ないですね)

--------------------------------------------------------
siokoshou さん

>トしています。呼ぶ方、呼ばれる方のどちらでもoutと明示するので、どちらを見ても多値を返

この点については、確かに、素敵だし爽やかだと思います。
だからこそ シーシャーパーであるというか、何と言うか、ごにょごにょ。

でも、何か違和感が、こう、あるんですよね。
慣れてしまえば、何て事は無いのでしょうけどね。

多分、以前 perl やった時に、

my(a, b) = Method(1, 2);

って書けてたから、余計にそう思うのかもしれません。

(result, value) = TryParse("数字");
if (!result) return false;

みたいな。
まあ、結局は、慣れということなんでしょうね。

# re: 値の出力はイコールの左辺に 2007/04/21 22:51 渋木宏明(ひどり)

>わざわざ型を作っちゃうこともあります。

int? 使えば?

# re: 値の出力はイコールの左辺に 2007/04/22 17:26 ghost_shell

int.TryParseを例にあげたのがよくなかったということなので・・・

 return XXX();
 
 という書き方がしたい場合でも、
 
 int val;
 XXX(out val);
 return val;
 
 のように3行にならざるを得ない。

ということを言いたい?

またoutの方がいらない場合でも(呼び出し側で)領域を用意するために1行書き添えないとならないのはちょっと嫌に思うことがある。

ValueType.TryParseはチェックあってのParseなので、きちんとした設計だと思いますよ。

それよりも広く利用されているメソッドに関して独自型を作ってしまうのは「愚」な臭いがするのだが。

# re: 値の出力はイコールの左辺に 2007/04/23 0:21 渋木宏明(ひどり)

>それよりも広く利用されているメソッドに関して独自型を作ってしまうのは「愚」な臭いがするのだが。

同意。

「作る」ってことは「間違いをも作りこむ」可能性と隣り合わせな訳で。

# re: 値の出力はイコールの左辺に 2007/04/23 6:42 Kazuki

TryParseは、個人的にあまり好きじゃありません。
下の例でiのスコープはifの中だけであってほしいのですがelseの中でも使えちゃうのがちょっと悲しいです。
----
string str = "XXXX";
int i;
if (int.TryParse(str, out i)) {
// do something
} else {
// iが使えちゃうのが嫌だ…
}
----
実際問題すごい問題になることはないので、TryParseをそのまま使ってます。

# re: 値の出力はイコールの左辺に 2007/04/23 10:21 R・田中一郎

渋木宏明(ひどり) さん

>int? 使えば?

TryParse() をカスタマイズするなら、その方がいいかも知れませんね。

int? i = IntTryParse("5");
if (i == null) エラー処理();

でもしませんよ。
TryParse() は、あくまでサンプルなんだってば^^;

-------------------------------------------------------
ghost_shell さん

>ということを言いたい?

単に、出力されるものは、左辺に持ってきたいという話です^^;

bool r = method(1, out i, out j, out k, out l, out m, out n);
MyClass r = method(1);

>ValueType.TryParseはチェックあってのParseなので、きちんとした設計だと思いますよ。

だから、TryParse は例として失敗だったと(ry

>それよりも広く利用されているメソッドに関して独自型を作ってしまうのは「愚」な臭いがするの

僕は、必ずしもそうだとは思っていません。

・・・が、これは別の論点でのお話なので(TryParseはあくまでも例ですし)だと思うので、またの機会に是非。

「素敵だし爽やかDay」とか「6月の東京わんくま勉強会」とか「僕が登壇する時」とか、6月の東京わんくま勉強会後の懇親会」とか。

-------------------------------------------------------
Kazuki さん

>TryParseは、個人的にあまり好きじゃありません。

だから・・・(ry
(だんだん短くなってくるw)

>下の例でiのスコープはifの中だけであってほしいのですがelseの中でも使えちゃうのがちょっ

これって、else 以下も同一ブロックってことなんでしょうか?
ちょっと違和感を感じますねぇ。

# re: 値の出力はイコールの左辺に 2007/04/23 10:54 渋木宏明(ひどり)

>単に、出力されるものは、左辺に持ってきたいという話です^^;

趣旨は理解できるけど、そのためだけにクラスを起こすのには反対。

そのクラスが他のメソッドの引数になるなど、元々別の利用方法があるなら別だけど、「複数の値のコンテナ」としての機能しかないなら、「自ら進んで」クラスを起こす理由としては弱すぎると思う。

人間は間違える生き物なので、10個のクラスで済ませておけば1個の間違いで済むところを、100個のクラスを作ったら10個以上の間違いが発生することになります。

10個の間違いを修正するコストは、1個の間違いを修正するコストの10倍で収まることは決してないわけで、単純に言えば、同じ結果が得られるなら「作るもの」の数はより少ない方が望ましいことになります。

他にも理由があって結局クラスは増えていくものだけど、「少ないに越したこた無い」ことに変わりは無いので、「クラスを増やす」には、見た目の満足度に勝る理由付けがあるべき、ということです。

ちなみに、C#3.0 になれば匿名型が利用できるので、自前でちびこいクラスを乱発しなくても、「複数の値のコンテナである場限りのクラス」を容易に受け止められるようになります。

# re: 値の出力はイコールの左辺に 2007/04/24 0:11 Kazuki

> だから・・・(ry
> (だんだん短くなってくるw)
いい例をください(*ノノ)キャッイッチャッタ

# re: 値の出力はイコールの左辺に 2007/04/24 10:14 R・田中一郎

渋木宏明(ひどり) さん

TryParse() の例であれば、僕も同意です。
それ以外のケースは、まさにケース・バイ・ケースということになるのではないかと。

>無いので、「クラスを増やす」には、見た目の満足度に勝る理由付けがあるべき、ということです。

そういうことですね。

>ちなみに、C#3.0 になれば匿名型が利用できるので、自前でちびこいクラスを乱発しなくても

これはいいことを聞きました。

-------------------------------------------------------
Kazuki さん

>いい例をください(*ノノ)キャッイッチャッタ

つ TryParse()

(同じじゃんっ!)

タイトル
名前
Url
コメント