じゃんぬねっと日誌

ネタと雑記と時々プログラミング

目次

Blog 利用状況

ニュース

お前スナイパーというよりクルクルパーだな

Sponsored Link

Rakuten

運営サイト

  • C# と VB.NET の入門サイト

書庫

VB の Select Case で多重評価を行う

たまに見かけます。言葉ではうまく説明できませんが下記のようなことです。

VB - Select Case で多重評価

' 複数の RadioButton の値によって処理を分岐する
Select Case True
    Case Me.RadioButton1.Checked : Me.Execute1()
    Case Me.RadioButton2.Checked : Me.Execute2()
    Case Me.RadioButton3.Checked : Me.Execute3()
    Case Else                    : Throw New System.Exception()
End Select


' 評価対象が複数ある分岐を Select Case によって簡素化する
Select Case True
    Case x > 1  : Me.Execute1()
    Case y <= 0 : Me.Execute2()
    Case z = 0  : Me.Execute3()
End Select

Select Case ステートメントは単一の評価によって多重分岐する時に使うものであるべきだと思います。気持ちはわからないまでもないですが、このような簡素化は癌になると思います。素直に If ~ Then ~ ElseIf ~ Else ~ End If を書いた方がまだ全然良いです。

VB - If ~ Then ~ ElseIf ~ Else ~ End If で多重評価

' RadioButton の値によって処理を分岐する
If Me.RadioButton1.Checked Then
    Me.Execute1()
ElseIf Me.RadioButton2.Checked Then
    Me.Execute2()
ElseIf Me.RadioButton3.Checked Then
    Me.Execute3()
Else
    Throw New System.Exception()
End If


' 複雑な条件を Select Case によって簡素化して分岐する
If x > 1 Then
    Me.Execute1()
ElseIf y <= 0 Then
    Me.Execute2()
ElseIf z = 0 Then
    Me.Execute3()
End If

これが汚らしいと感じたり関連が薄いと思うのであれば、ガード句を使った方が良いかもしれません。コメントの場所にも困らずに済みます。

VB - ガード句を使って単一評価ごとに分断する

' RadioButton1 が選択されている場合は処理 1 を行う
If Me.RadioButton1.Checked Then
    Me.Execute1()
    Return
End If

' RadioButton2 が選択されている場合は処理 2 を行う
If Me.RadioButton2.Checked Then
    Me.Execute2()
    Return
End If

' RadioButton3 が選択されている場合は処理 3 を行う
If Me.RadioButton3.Checked Then
    Me.Execute3()
    Return
End If

' ここまで来るような流れがあるなら「例外」をスローせざるを得ない (ネタ元: 龍虎の拳)
Throw New System.Exception()


' 処理 1 を行う
If x > 0 Then
    Me.Execute1()
    Return
End If

' 処理 2 を行う
If y <= 0 Then
    Me.Execute2()
    Return
End If

' 処理 3 を行う
If z = 0 Then
    Me.Execute3()
    Return
End If

これは、Select Case はもっと使える - Visual Basic 中学校 [nifty.com] を拝見して思い出したかのように書いた記事ですが前提条件が間違っておりました。謹んでお詫び申し上げます。それとは別の話になりますが、5. はバグの温床にしかならないので利用は避けた方が良いと思います。

投稿日時 : 2007年7月20日 9:41

コメントを追加

# re: VB の Select Case で多重評価を行う 2007/07/20 11:19 片桐

あぅ(大汗)

select case true ~ end select
select case False ~ end select
使いまくる人……

特に画面入力項目のチェックとか(^^;

select case true
case not(isNumeric(Hoge))
case hoge >100
case hoge <0
end select

みたいなカンジなんですけどね。
とにかく最初からチェックしたいこと列挙して、どこか一個当たってたらメッセージ吐いて終わり~、みたいな時には便利だし、追いかけやすいから(^^;;;;

……………(((^^;;;あぅあぅあぅ

# re: VB の Select Case で多重評価を行う 2007/07/20 11:49 れい

というか5って遅いしメモリ食うしで、
かなり特殊な状況でないとだめだめな方法かと。

でもselect case CONSTANT case: variableは
いいと思いますが。

>Select Case ステートメントは単一の評価によって多重分岐する時に使うものであるべきだと思います。

単一の評価ではないですか?
各caseに対してCONSTANTと等しいか、単一の評価をしているので
select case variable case CONSTANT:
とまったく同じかと。

慣れの問題?

# re: VB の Select Case で多重評価を行う 2007/07/20 12:00 じゃんぬねっと

明らかに私の書き方が悪いですね。これでも迷った挙句選んだ言葉だったのですが... どういう言葉を使うべきなのか未だにわかりませんが、最初の "評価式" に対しての期待値が複数ある場合に利用すべきであってということが言いたかったです。

最初に True と書いてしまって評価式を後手にまわすこと自体に異を唱えると書いた方が御幣がないかもしれません。この方法を取られると Case 句では何とでも True になるように書いてしまえば良いわけで、レビュー者の期待を裏切る書き方だと思います。

実際、このソースをして混乱してしまう人は多いのではないでしょうか。人間には期待というのがありますから。

# re: VB の Select Case で多重評価を行う 2007/07/20 12:08 まどか

#5がだめだめなのは同じ

3は活用派です。
むしろ"ElseIf"嫌悪派です。
もちろん使うべき場面は考慮します。
速度優先や条件内の変数に統一性がない場合は使いません。

Select Case True
Case X > Y
Case X < Y
Case Else 'あえてX = Yと書く場合もある
End Select

可読性と保守性はElseIfとは比べ物にならないと思っています。
例のラジオボタンの場合、Case+対応ステートメントの単位で行単位追加削除できるのは魅力です。
気をつけなければならないのは、評価順が上から書いた順であることでしょうか。(Ifのネストから見れば暗黙の仕様みたいな)

# re: VB の Select Case で多重評価を行う 2007/07/20 12:10 未記入

私もIf ~ Then ~ ElseIf ~ Else ~ End If で多重評価
がよいと思います。Select Caseで複数条件を判定するのはSelectの意味と合わないと思います。
まぁ、Is〇〇のメソッドを作って、なおかつテストファーストが正しくなされていれば、本人の自由と言えなくもないのですが、可読性を考えると、やはり私は素直に多重評価が良いと思います。

# re: VB の Select Case で多重評価を行う 2007/07/20 12:11 nagise

プログラマの頭の体操としての「こんなことも出来る!」ってのと、
業務でやるプログラミングとは違いますからね。

パズルのほうは一人で、もしくは少数の同士とニヤニヤしながらやっていればいいんですが
業務のプログラミングはよく知らない大勢の人間相手にプログラム言語という
言語を用いて意思疎通を必要とする共同作業ですから、アルゴリズムひとつとっても
分かりやすさとか違う評価軸がでてきますよね。

# re: VB の Select Case で多重評価を行う 2007/07/20 12:17 未記入

書き忘れた事がありますので書きます。
SelectCaseを使う人は何故OrElse 演算子とAndAlso 演算子を使わないのでしょうか?

単純に

IF A = X OrElse B = Y Then

とやった方が解り易いと思うのですが・・・

# re: VB の Select Case で多重評価を行う 2007/07/20 12:17 まどか

#あ、ElseIf否定ではなく、3番OK派です。念のため。

> 人間には期待というのがありますから。

私が書いたやつなんかは、仕様を表現する言葉からの期待を満たしていませんか?
Caseが同インデントで視認性がよいので仕様を満たしているかどうかがぱっと見わかると思うんですが。

#あくまで乱用はしません。というか無理やりこの形にする場面は無いと思いますよ。

# re: VB の Select Case で多重評価を行う 2007/07/20 12:19 まどか

> SelectCaseを使う人は何故OrElse 演算子とAndAlso 演算子を使わないのでしょうか?

まずはその選択作業があると思うのですが、
というかそれ前提でいろいろ書いてます。

# re: VB の Select Case で多重評価を行う 2007/07/20 13:10 某B

>私が書いたやつなんかは、仕様を表現する言葉からの期待を満たしていませんか?

そっちの期待じゃなくて言語仕様レベルの期待だと思う。
Select Case Trueの段階で頭を切り替えられる人ならかまわんでしょう。

今回に限った話じゃないけどと自分のセンスが全共通のセンスだと思ってコードを組む人が未だに多い。
特にCOBOLやVBのような偏ってしまう分野に多く見られるんだけど。
擁護しとくと全メンバーが共通の認識だったら構わないと俺は思う。

だからこれは前提で変わるかな。
一人で開発やっているわけじゃないってところも考えてほしいことがある。
積極的に使う理由は見つからないので使わないが無難に1票かな。

# re: VB の Select Case で多重評価を行う 2007/07/20 13:23 某B

いやまて。仕様を表現っていうけど仕様書の書き方次第じゃないか。
If ~ ElseIf End Ifだって仕様書に沿う書き方になるはずだ。
ガード句を使う場合に関してもそこで処理が中断するというフローになっているなら仕様に沿っている。

# re: VB の Select Case で多重評価を行う 2007/07/20 13:55 まどか

> Select Case Trueの段階で頭を切り替えられる人ならかまわんでしょう

うんうん、わかります。
どっちかっていうと、是非ではなくその書き方にたどり着けない人のほうが気になりますがね。

で、Select Case Trueを1単語にしたステートメントがあれば、今回の議論も無かったのかな?

> 特にCOBOLやVBのような偏ってしまう分野に多く見られるんだけど。

そういや、EVALUATE TRUEなんてのよくやってます。。。

# re: VB の Select Case で多重評価を行う 2007/07/20 14:06 某B

> どっちかっていうと、是非ではなくその書き方にたどり着けない人のほうが気になりますがね。

それを言われるとちとつらいw
が「ん!?」とは思う人は多いんじゃないかな。
まあでも次の瞬間ブロック内を見ればわかるしなぁ。

結局のところこういったものって大規模開発であっても一環していれば問題ないのかもしれない。
個人的にはこれだよという程度のものなのかも。
これまでのコメントの名前を見るとCやJavaの分野系の人だと避ける傾向にあるような気がする。

ひょっとしてVBばかりやっている人にとってはむしろ常識だったりする?

# re: VB の Select Case で多重評価を行う 2007/07/20 14:25 まどか

> CやJavaの分野系の人だと避ける傾向にあるような気がする。

わかります。
ただ「VBだから」ってのは言語表現が異なることも含んでいると思います。

> 大規模開発であっても一環していれば問題ないのかもしれない。

でもコーディング規約にするような問題でもないと思います。
これは私の言う「活用」と重なります。

> ひょっとしてVBばかりやっている人にとってはむしろ常識だったりする?

そんなことは無いです。(と思います)
今回の使用例が積極的に前面に出た入門書を見たこともありませんし。
で私は先に書いたような理由を根拠に使い分けていますし。
先に言ったように、たどり着けない人は
・If A = 1 Then Return True
・Return (A = 1)
の後者へたどり着けない人でしょう。
つまり、理屈をわかってる人が使う例ではないですかね?
#事が大げさになりすぎてるような気もしますが。。。

# re: VB の Select Case で多重評価を行う 2007/07/20 16:19 れい

>一人で開発やっているわけじゃないってところも考えてほしいことがある。

そんなわかりづらいかなぁ?
SELECTに期待するものというか、覚え方の違いでは?

「評価式と一致するものを探す」
という動作で覚えた人と
「どれか一つを選ぶ(Selectする)」
という動作で覚えた人の違いでは?
前者なら、評価式がConstだと確かに変に思えます。

VBを覚えたころ、当然switchとの違いを学んだわけですが、
Selectはまさに一つ選ぶためにあって、
だからbreakが要らないんだと覚えました。

そう考えると、
たくさんの選択肢の一つを選ぶ目的に
Selectを使うのは私には違和感ありません。
たとえ評価式がTrueであろうと他のConstantであろうと。

でもswitchにconst入ってたら激しく気持ち悪いですねぇ。

>今回に限った話じゃないけどと自分のセンスが
>全共通のセンスだと思ってコードを組む人が未だに多い。

んっと私のセンスはずれてるっという批判かな?
昔から散々議論されてますが、
プログラミングセンスって結局合いませんよね?

「自分のセンスが全共通のセンスだ」と思ってても、
「自分のセンスが全共通のセンスじゃないからあわせなきゃ」と思っても、結局合わなくって。

だからみんなで話し合って規約を決めるべきで、
規約があるなら従うべきで。

規約を決めるのになるべくみんなのセンスに合ってたり、
便利だったり、速度が速かったりするほうがいいと思うんで、
いろんな人の意見を聞くのは重要ですよね?

というわけでじゃんぬさんのセンスに
「合わない」方に一票なんです。

Select Case Trueは実際には
あまり使いませんが。

>CやJavaの分野系の人だと避ける傾向にあるような気がする。

ちなみに私はC++の時間が一番長いです。

# re: VB の Select Case で多重評価を行う 2007/07/20 16:23 れい

追記。

>規約を決めるのになるべくみんなのセンスに合ってたり、
>便利だったり、速度が速かったりするほうがいいと思うんで、
>いろんな人の意見を聞くのは重要ですよね?

>というわけでじゃんぬさんのセンスに
>「合わない」方に一票なんです。

そして、
みなさんの反対・賛成とその理由を聞きたいと思っています。

>このような簡素化は癌になると

癌になるかなぁ?
どれかを選んでるだけなんだけど。

# re: VB の Select Case で多重評価を行う 2007/07/20 16:57 じゃんぬねっと

> どれかを選んでるだけなんだけど。

どうも最初のソース例自体もまずかったみたいですね。このレベルなら個人のスタイルのような気がします。最近某所でも似たような論議がありましたが。何か申し訳ないです。

実際に私が見たのは、Case に挙げられているものに関連がなかったのです。何も考えずに記事用に単純な例に書き換えてしまったのが間違いでした。なぜ非難として書いている途中で、理由について自分なりに考えなかったのだろう...

それでも使わないとは思いますが、それはあくまでも自分で考えている一環したルールに合わないという理由しかないと思います。Case 句に書く内容を限定する (期待値のみを書き、式を書かない) ようにしているからという、前提があってのことになると思います。

癌になりえるとすれば改変の時なのでしょうけど、これは If ~ Then ~ ElseIf ~ End If でも普通に起こりえます。私は改変時を気にして、ガード句を (すべてに使っているわけではないですが) 結構使っているような気がします。それでもヘンなところに Else If をぶら下げてしまう人もいますけど... orz

> Selectはまさに一つ選ぶためにあって、
> だからbreakが要らないんだと覚えました。

脱線話ですが、C# だと break; は実質必要なかったりしますね。付けていないと違和感があったりしますが。VB やっているとたまに Select Case のノリで忘れてしまいコンパイラに叱られます。フォール スルーさせる気なんてサラサラないから「勝手に付けてくれていいよ」といつも思います。orz

# re: VB の Select Case で多重評価を行う 2007/07/20 17:20 某B

強制する意図はなかったんだけど断定的に書いてしまって申しわけない。
俺はどちらかというとVBのSelect Caseの仕様に対して文句を言いたいのかもしれない。
Select Caseは非常に柔軟性に優れすぎている。

Case 1, 2, 3

みたいなのはアリだと思う。
switchだと

case 1:
case 2:
case 3:

みたいになるだけの話だし。
(こうやって考えること自体がVBの考え方に反している可能性ももちろんわかって書いてる)

だからCaseの中に評価式が書かれてしまうのがいやなのかと考えたんだけど、Is > 100なんかも式なわけだから一意にそういうわけでもない。
ただここで注目したいのがIsにかかるのは最初にSelect Caseに書かれた式の結果に対してだ。
つまりSelect Caseで最初に「この値は何よ?」っていう前提で考えてそれ以外の「値」の評価がCase式に書かれるのが違和感があってイヤなんだと思う。

最初の例もRadioButton1とRadioButton2とRadioButton3は評価式としては無縁の関係のはずだし。
(まあ実際にはGroupBoxに入れられていたりして単一になるから仕様としては無縁ではないんだけど。)

# re: VB の Select Case で多重評価を行う 2007/07/20 17:24 某B

げ。日本語下手だw

要するにSelect Caseをどういう時に使うかという指針の違いでしかないと思う。
反対していた理由としては「分岐の基になる式は1つでありたいから」になると思う。
みんなの意見を見てswitch的な狭い使い方が必ずしも正しいとは言い切れないと思った。
ただ狭くすることで見やすくなるというのは個人的には信じている。
C、Java云々の話を出したのもそういうところから来ていたと思う。

# re: VB の Select Case で多重評価を行う 2007/07/20 17:39 裏口

修正された内容を見ると納得できました。

# 最初に見たときはVB特有の言語仕様があるのかと理解に
# 苦しみました。

# re: VB の Select Case で多重評価を行う 2007/07/20 19:19 れい

みんなと同じだと安心するタイプです。
どうやってもやっぱり某Bさんやぬねっとさんとは
センスがずれてるっぽいです。

不安です…。
明日からどうやって生きていけばいいんだろう?

>実際に私が見たのは、Case に挙げられているものに関連がなかったのです

本当に関連しないものはCaseに入れようが無い気がするんですがねぇ。
少なくとも分岐するという関係があるから
その場所で分岐しているわけで。
じゃんぬねっとさんの例くらいだとあるなぁ。

本当に関連がないとするとかなりの「困ったさん」が
作ったコードだと思うんで
それってSelectの使い方の問題じゃないような。

私は他人が見るソースの場合、
Selectは「場合わけ」Ifは「条件分岐」で使い分けてました。
多少違和感あるSelectでも、
「場合わけ」なニュアンスを伝えたい場合は
(他人にわかりやすいと思って)
がんばってSelectを使ってました。

他人が見ない場合はElseIfの連結で書いてました。

もしかしてありがた迷惑ってやつですか?!

# re: VB の Select Case で多重評価を行う 2007/07/20 19:25 れい

>どうやってもやっぱり某Bさんやぬねっとさんとは

「ぬねっとさん」って誰?
じゃんぬねっとさん。

# re: VB の Select Case で多重評価を行う 2007/07/20 21:18 RUN

自分もSelect caseでCase側で数式を使うのは嫌いですね。
単純な理由としては、
日本語にし難い。

元々、case文自体が日本語にし難いので余り好みではないのですがw

# re: VB の Select Case で多重評価を行う 2007/07/20 23:18 まどか

> 本当に関連しないものはCaseに入れようが無い気がするんですがねぇ。

For Each idol As idolinfo In JapaneseIdols
Select Case True
Case idol.Bust >= 80
idol.Rank = Rank.A
Case idol.Age > 17 And idol.Age < 27
idol.Rank = Rank.B
Case idol.IsShortHair
idol.Rank = Rank.C
Case Else
idol.Rank = Rank.D
End Select
Next

関連が無い=変数に統一性が無い場合でも、条件の優先度および目的がひとつという場面がそれなりにあると思います。
If文を優先順に縦に並べるのとの違いは、見た目Selectブロックに入れることができるということに尽きます。
当然動機が不純だという意見になんら反論はありません。
私はこっちのほうがきれいだと思っているだけです。

# re: VB の Select Case で多重評価を行う 2007/07/20 23:32 通りすがり~3

> For Each idol As idolinfo In JapaneseIdols
> Select Case True
> Case idol.Bust >= 80
> idol.Rank = Rank.A
> Case idol.Age > 17 And idol.Age < 27
> idol.Rank = Rank.B
> Case idol.IsShortHair
> idol.Rank = Rank.C
> Case Else
> idol.Rank = Rank.D
> End Select
> Next

これは微妙ですね。
まったく関連がないとは言いませんがそれほど強いわけではないので、もっと使う場面を限定してくれないと。
とりあえずこの場面ではガード句を使ったIfを使ったメソッドを1本かくでしょう。

# re: VB の Select Case で多重評価を行う 2007/07/21 0:49 れい

まどかさんとはセンスが近いようですね。
私の言いたいことを言ってくれました。
ですが

>私はこっちのほうがきれいだと思っているだけです。

最初の条件は合いませんね
個人的にはCharacterが先かと。

>当然動機が不純だという意見になんら反論はありません。

不純かなぁ
そろそろいい年なので
idol.Bust >= 80でRank.Aというのもどうかと。

まどかさんは即物的なのですねぇ
見た目も気にしますが、やはり中身っていうか、
意味論的にSelectなんだけどなぁ。

# re: VB の Select Case で多重評価を行う 2007/07/21 14:27 某B

冗談でもそんな風に言われてもなぁ。
最初は否定から入ってしまったけどそこまで言われるとセンスの違いでしかなくてそれはもう仕方がないと思う。
グループ開発をやる時にいやがるメンバが多そうなら避ける程度で別にいいんじゃないかなって思うんだけど。

# re: VB の Select Case で多重評価を行う 2007/07/21 18:42 未記入

確かにグループ開発では、コンセンサスが第一だと思います。ただし、今現在のグループだけではなく、未来の保守要員グループまでそのコンセンサスを守らせる事が出来るかどうかが問題ではないでしょうか?
もしこれが可能ならば、どんなコーディング法でもかまわないと私は思います。

# re: VB の Select Case で多重評価を行う 2007/07/21 20:16 frontline

最後の「未来の保守要員グループまで」を考えた意見、今の私にはものすごくうなずけます。

「できるかどうかと言われれば、できる」と、「誰もができる」というものが並んだ場合、やはりチーム/長期開発では「誰もができる」を選ぶのが定石かと。それも、「その時点で関与していない、第三者がメンテすることになっても、本来のロジック以外の面で頭を悩ます必要が無い」という選択肢を取るのが重要かと。

今そういうのに直面してまして ^-^;

脱線気味でごめんなさい。

# re: VB の Select Case で多重評価を行う 2007/07/21 22:28 まどか

むぅ、なんか違うぞ。

>>私はこっちのほうがきれいだと思っているだけです。
>
>最初の条件は合いませんね
>個人的にはCharacterが先かと。

>当然動機が不純だという意見になんら反論はありません。
>
>不純かなぁ
>そろそろいい年なので
>idol.Bust >= 80でRank.Aというのもどうかと。

二つともIfとSelectを比べての話ですよう!
言っておきますが条件の値も適当です。
ちなみに爆○は嫌いです。無くても困るが。

# 染み着いちゃってるもの 2007/07/21 22:48 まどか の ブログ

染み着いちゃってるもの

# re: VB の Select Case で多重評価を行う 2007/08/27 10:59 流しのインストーラ

もう議論は終わってしまったのでしょうか。
(結論はセンスの問題になったのでしょうか)

以下のようなロジックがありました。

Select Case True
 Case sレベル = ""
  Return False

 Case 5 < Cint(sレベル)
  Return True

 Case ...
:
End Select

Return False

VB.NET(2003) のオンラインヘルプを見てみると Case の評価順について記述がありません。
>引数 testexpression が Case 句の引数 expressionlist のいずれかの式に一致すると...
例では sレベル="" の時、下から評価されるとエラーになります。

じゃんぬねっとさんの
>最初に True と書いてしまって評価式を後手にまわすこと自体に異を唱える
のじゃんぬさんのセンスに「合う」方に一票です

タイトル  
名前  
URL
コメント