C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

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

Re[3]: CBoolについて(#63492スレ:63519より分岐)


(過去ログ 106 を表示中)

[トピック内 4 記事 (1 - 4 表示)]  << 0 >>

■63521 / inTopicNo.1)  CBoolについて(#63492スレ:63519より分岐)
  
□投稿者/ shu (60回)-(2012/09/04(Tue) 12:27:14)

分類:[雑談] 

No63519 (魔界の仮面弁士 さん) に返信

> 言いたいことは分かります。
理解していただきありがとうございます。


> >> CBoolはBoolean型への変換を行う関数であって
>>何を Boolean 型に変換する事を目的としているのでしょう。
>
> この質問に対する答えもお聞きしたいです。
>
変換元の集合がTrue,Falseに対し1:1で対応していてTrue,False(Yes,No/On,Off)
の意味として使用している場合、かつCboolでの変換で思ったとおりに変換が出来るときに使用することを
目的としていると思います。例としては
(1)0をFalse,1をTrueの代わりとして扱っている場合
(2)"True"をTrue, "False"をFalseの代わりとして扱っている場合、(ファイルへ保存したデータの読込時など)
(3)Object型にBoolean値を格納している場合 (DBからの読込の場合など)
※(1)のケースがビットフラグ値のケースに似ていますがあくまでも扱う値がBooleanに対応している
値であるということが必要なのではないかと思っています。


> 「互換性のために」という文からは、以前は使われていたけれども
> 現在は推奨されない変換処理であるという意図を感じるのですが、だとすると
> どういう時に CBool は使われるべきでしょうか。(あるいは、CBool 自体を
> 将来的には廃止するべきだ、という思いがあるのでしょうか)
上記例の(1),(2)については特定の定数に対する1:1の対応付けを強制しているので
このような変換はそもそも
A <> 0
B = 1
C = "True"
D <> "False"
という演算結果のBoolean値を使った方が確実(明確な仕様がFrameworkレベルで定められれば
CBoolの方が確実ですが)なので結局私が今思いつくところではObject型にBox化されたBoolean値を
UnBox化するときに使うのが良いのではないでしょうか?
ただし(2)のケースで出力した文字列がToStringによるものであればCBoolで元の値に戻すというのは許容範囲かもしれません。

引用返信 編集キー/
■63529 / inTopicNo.2)  Re[1]: CBoolについて(#63492スレ:63519より分岐)
□投稿者/ 魔界の仮面弁士 (51回)-(2012/09/04(Tue) 14:43:08)
No63521 (shu さん) に返信
> 理解していただきありがとうございます。

shu さん的には、下記の因数判定関数(IsFactor)の実装も NG であろうかと予測します。
http://msdn.microsoft.com/ja-jp/library/cc344148.aspx

もしこれが、奇数判定(IsOdd)の場合はどうでしょう?
Mod 2 なら、答えは 0 / 1 の二値になりますが…。


ちなみに自分の場合は、どちらも CBool を使わずに実装します。
もしも後輩が書いているのをみた場合、後者はスルーしますが、
前者は、次回からは別の書き方にするように指導するかも知れません。



>>>何を Boolean 型に変換する事を目的としているのでしょう。
>>
>> この質問に対する答えもお聞きしたいです。
>> 
> 変換元の集合がTrue,Falseに対し1:1で対応していて

1 対多の場合は使用するべきでは無く、
1:1 となる場合にのみ使用するべき、という話ですね。

・「True なもの、False なもの、どちらでも無い物」に分かれる集合は除外される。
・「True なもの/False なもの」だけの集合であっても、
 True / False それぞれを表す表現が複数あった場合は除外される。

データ型に着目して考えてみた場合は、

・String 管理されたデータを変換する場合は、
 Boolean.TrueString / Boolean.FalseString の二値の場合のみ使用する。

・整数型の場合は、「0」と「0以外の特定の1つの数値」の場合に限定して利用。
 たとえば 0 / 1 や 0 / -1 や 0 / 9 などで使用するのは良いが、
 0 / 1〜9 などのパターン(No63518 など)では使用しない。

という認識でよろしいでしょうか。

# 実数型の場合は、今回触れていなかったので考慮外。
# Decimal のように、0 と 0.00 とで別のバイナリになる場合もあるので、
# 下手に触れるとややこしいことになりそう。(^^;


上記のとおりだとしたら、「e.State And DrawItemState.Selected」の結果は、
DrawItemState.None / DrawItemState.Selected のどちらか二値である
という見方をすることで許容されそうにも感じますが、これは不味いのでしょうか。



> Cboolでの変換で思ったとおりに変換が出来るときに使用することを
> 目的としていると思います。
こちらは、誰にとっての「思ったとおり」でしょうか?

ある開発者が「予想」した変換規則があって、それと同様の
動きを見せた場合に使うべき、という話でしょうか。
(開発者Aと開発者Bの「思ったとおり」は、異なるかもしれません)



> Object型にBox化されたBoolean値をUnBox化するときに使うのが良いのではないでしょうか?
私は逆に、ボックス化解除の目的では CBool を使いたく無い派です。

IL 的には unbox だけで済む処理が、わざわざ VB の変換サービスを
通すことになってしまいますので、そのような場合には
型変換(CBool / CType)ではなくキャスト(DirectCast / TryCast)を好みます。


ただ、それだと読みづらいという意見が出たこともあるので、多少の
パフォーマンス劣化は無視して、あえて CBool を使う事はありますけれども。


> 演算結果のBoolean値を使った方が確実
私も基本的にはその認識です。


> (明確な仕様がFrameworkレベルで定められればCBoolの方が確実ですが)
CBool は言語固有実装なので、Framework 側では定義されないでしょうね。
(VB の仕様については、先述したとおり)

.NET Framework の場合は、
 Convert.ToBoolean(Int32) →0 は False、それ以外は全て True。
が明文化されていますね。

IL レベルでは、native int の 0 は false 、それ以外は true です。
If 文相当の条件分岐としては、
 0x39(brfalse / brnull / brzero) → 0 ならばジャンプ
 0x3A(brtrue / brinst ) → 0 以外ならばジャンプ
が用意されています。

引用返信 編集キー/
■63530 / inTopicNo.3)  Re[2]: CBoolについて(#63492スレ:63519より分岐)
□投稿者/ shu (63回)-(2012/09/04(Tue) 15:48:04)
No63529 (魔界の仮面弁士 さん) に返信

> shu さん的には、下記の因数判定関数(IsFactor)の実装も NG であろうかと予測します。
> http://msdn.microsoft.com/ja-jp/library/cc344148.aspx
>
> もしこれが、奇数判定(IsOdd)の場合はどうでしょう?
> Mod 2 なら、答えは 0 / 1 の二値になりますが…。
Mod 2の答えは余りでありTrue,Falseを表すものではないのでNGです。



>
> >>>何を Boolean 型に変換する事を目的としているのでしょう。
> >>
> >> この質問に対する答えもお聞きしたいです。
> >>
>>変換元の集合がTrue,Falseに対し1:1で対応していて
>
> 1 対多の場合は使用するべきでは無く、
> 1:1 となる場合にのみ使用するべき、という話ですね。
>
> ・「True なもの、False なもの、どちらでも無い物」に分かれる集合は除外される。
> ・「True なもの/False なもの」だけの集合であっても、
>  True / False それぞれを表す表現が複数あった場合は除外される。
>
> データ型に着目して考えてみた場合は、
>
> ・String 管理されたデータを変換する場合は、
>  Boolean.TrueString / Boolean.FalseString の二値の場合のみ使用する。
>
> ・整数型の場合は、「0」と「0以外の特定の1つの数値」の場合に限定して利用。
>  たとえば 0 / 1 や 0 / -1 や 0 / 9 などで使用するのは良いが、
>  0 / 1〜9 などのパターン(No63518 など)では使用しない。
>
> という認識でよろしいでしょうか。
良いと思います。


> # 実数型の場合は、今回触れていなかったので考慮外。
> # Decimal のように、0 と 0.00 とで別のバイナリになる場合もあるので、
> # 下手に触れるとややこしいことになりそう。(^^;
>
>
> 上記のとおりだとしたら、「e.State And DrawItemState.Selected」の結果は、
> DrawItemState.None / DrawItemState.Selected のどちらか二値である
> という見方をすることで許容されそうにも感じますが、これは不味いのでしょうか。
見方としてNone(=0)をFalseに対応させ、SelectedをTrueに対応させる
ということが出来なくはないですが、そう考えてしまうと
A And Maskの結果が論理上、
Integerになったり (Maskが2つ以上のフラグ(B or Cなど)の値である場合)
Booleanになったり (Maskが1つのフラグである場合)
してしまい分かりにくくなるということになります。
※Booleanになるというのは前述した1:1の関係を保ちつつBooleanへの変換が可能なことを
 言うとします。


>>Cboolでの変換で思ったとおりに変換が出来るときに使用することを
>>目的としていると思います。
> こちらは、誰にとっての「思ったとおり」でしょうか?
>
> ある開発者が「予想」した変換規則があって、それと同様の
> 動きを見せた場合に使うべき、という話でしょうか。
> (開発者Aと開発者Bの「思ったとおり」は、異なるかもしれません)
プロジェクト内での仕様で考えればよいと思います。


>>Object型にBox化されたBoolean値をUnBox化するときに使うのが良いのではないでしょうか?
> 私は逆に、ボックス化解除の目的では CBool を使いたく無い派です。
>
> IL 的には unbox だけで済む処理が、わざわざ VB の変換サービスを
> 通すことになってしまいますので、そのような場合には
> 型変換(CBool / CType)ではなくキャスト(DirectCast / TryCast)を好みます。
>
>
> ただ、それだと読みづらいという意見が出たこともあるので、多少の
> パフォーマンス劣化は無視して、あえて CBool を使う事はありますけれども。
私もどちらかというとDirectcastを使うようにはしています。


>>(明確な仕様がFrameworkレベルで定められればCBoolの方が確実ですが)
> CBool は言語固有実装なので、Framework 側では定義されないでしょうね。
> (VB の仕様については、先述したとおり)
>
> .NET Framework の場合は、
>  Convert.ToBoolean(Int32) →0 は False、それ以外は全て True。
> が明文化されていますね。
>
> IL レベルでは、native int の 0 は false 、それ以外は true です。
> If 文相当の条件分岐としては、
>  0x39(brfalse / brnull / brzero) → 0 ならばジャンプ
>  0x3A(brtrue / brinst ) → 0 以外ならばジャンプ
> が用意されています。
仕様としてはFalseを0に対応付けするのはいろいろ内部処理上都合がよいので
変わることはないでしょうね。
引用返信 編集キー/
■63548 / inTopicNo.4)  Re[3]: CBoolについて(#63492スレ:63519より分岐)
□投稿者/ shu (67回)-(2012/09/05(Wed) 17:06:28)
No63530 (shu さん) に返信

コメントが付かないのでここで解決とします。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -