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

わんくま同盟

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

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

ツリー一括表示

異なるEnumを=で比較できないようにする /かば (24/10/14(Mon) 18:51) #103344
Re[1]: 異なるEnumを=で比較できないようにする /とくま (24/10/15(Tue) 09:48) #103349
│└ Re[2]: 異なるEnumを=で比較できないようにする /WebSurfer (24/10/15(Tue) 12:33) #103355
Re[1]: 異なるEnumを=で比較できないようにする /とっちゃん (24/10/15(Tue) 11:57) #103351
│└ Re[2]: 異なるEnumを=で比較できないようにする /とっちゃん (24/10/15(Tue) 12:01) #103353
Re[1]: 異なるEnumを=で比較できないようにする /WebSurfer (24/10/15(Tue) 13:07) #103356
Re[1]: 異なるEnumを=で比較できないようにする /radian (24/10/16(Wed) 10:19) #103365
  └ Re[2]: 異なるEnumを=で比較できないようにする /かば (24/10/16(Wed) 21:29) #103375 解決済み


親記事 / ▼[ 103349 ] ▼[ 103351 ] ▼[ 103356 ] ▼[ 103365 ]
■103344 / 親階層)  異なるEnumを=で比較できないようにする
□投稿者/ かば (1回)-(2024/10/14(Mon) 18:51:24)

分類:[.NET 全般] 

2024/10/14(Mon) 18:52:12 編集(投稿者)
VB.NET2015を使っております。

    Public Enum Enum1
        Square = 1
        Circle = 2
        Other = 3
    End Enum

    Public Enum Enum2
        Square = 4
        Circle = 8
        Triangle = 12
    End Enum


という二つのEnumを宣言したとします。


そしれ、これら別々の変数として宣言したとします。

        Dim V1 As Enum1 = Enum1.Circle

        Dim V2 As Enum2 = Enum2.Square

この状態で以下のようなIf文を書いても
エラーとはならず、ビルドできてしまいます。

        If V1 = Enum2.Square Then


        End If

        If V1 = V2 Then


        End If

これらは違う変数なので、比較できてしまうと
バグの温床となってしまいます。

Option Strict On
など試してみたのですが、やはりビルドできてしまいます。

どうにか区別できるようにする方法はないでしょうか?




[ □ Tree ] 返信 編集キー/

▲[ 103344 ] / ▼[ 103355 ]
■103349 / 1階層)  Re[1]: 異なるEnumを=で比較できないようにする
□投稿者/ とくま (17回)-(2024/10/15(Tue) 09:48:00)
No103344 (かば さん) に返信
Const を区別するような話になっちゃうかもね。
Dim V2 As Enum2 = Enum1.Square
これも通るので、サブプロシージャの仮引数とかにしてもコンパイルエラーには
ならなくて、かなり難しそう。

ごりごりと比較専用の関数とか書けば、実行時エラーにはできるかもだけど、
設計上、名称で違いを分かりやすくするとか、もう一つ深い Class に定義する
とかで、見た目で注意するのが落としどころかも…コスパ的に。
[ 親 103344 / □ Tree ] 返信 編集キー/

▲[ 103349 ] / 返信無し
■103355 / 2階層)  Re[2]: 異なるEnumを=で比較できないようにする
□投稿者/ WebSurfer (2922回)-(2024/10/15(Tue) 12:33:49)
No103349 (とくま さん) に返信

> Dim V2 As Enum2 = Enum1.Square
> これも通るので、

Option Strict On なら通らないのでは? 質問者さんは

> Option Strict On など試してみたのですが、

とのことです。
[ 親 103344 / □ Tree ] 返信 編集キー/

▲[ 103344 ] / ▼[ 103353 ]
■103351 / 1階層)  Re[1]: 異なるEnumを=で比較できないようにする
□投稿者/ とっちゃん (835回)-(2024/10/15(Tue) 11:57:40)
No103344 (かば さん) に返信
> これらは違う変数なので、比較できてしまうと
> バグの温床となってしまいます。
>
> Option Strict On
> など試してみたのですが、やはりビルドできてしまいます。
>
> どうにか区別できるようにする方法はないでしょうか?
>
VS2022で、Option Strict On をつければ、IDEレベルでエラーメッセージ出してくれるようです(VS2015のままでもC#なら同様の記述はエラーになるはず)
これを機にVS2022に移行することを考えてみてはいかがでしょうか?

VS2015なので、.NET 4.0 か 4.5 がベースになっていると思いますが、どちらもVS2022でビルドできます。
VS2015とVS2022では環境面で異なる部分もありますが(マクロや、VSIXのほか、IDE自体が64bitになってるなど)
最新環境を使えるということ以外にこういった開発効率などに直結する部分も大きく改善されています。

[ 親 103344 / □ Tree ] 返信 編集キー/

▲[ 103351 ] / 返信無し
■103353 / 2階層)  Re[2]: 異なるEnumを=で比較できないようにする
□投稿者/ とっちゃん (836回)-(2024/10/15(Tue) 12:01:22)
No103351 (とっちゃん さん) に返信
> VS2022で、Option Strict On をつければ、IDEレベルでエラーメッセージ出してくれるようです(VS2015のままでもC#なら同様の記述はエラーになるはず)
> これを機にVS2022に移行することを考えてみてはいかがでしょうか?
>
すいません。検証不足でした。
代入はエラーになったけど、比較は何も文句言われませんでした><

C#ならエラーになるんですけどね。
[ 親 103344 / □ Tree ] 返信 編集キー/

▲[ 103344 ] / 返信無し
■103356 / 1階層)  Re[1]: 異なるEnumを=で比較できないようにする
□投稿者/ WebSurfer (2923回)-(2024/10/15(Tue) 13:07:55)
No103344 (かば さん) に返信

VB.NET では、

If V1 = Enum2.Square Then

の所で比較前に暗黙の型変換がされて(C# でいうと if ((int)v1 == (int)Enum2.Square) と
いうようになって)エラーにならないようです。

ただ、Microsoft のドキュメントなどに「比較演算子を利用すると列挙型は比較前に暗黙の型
変換がされる」というような記述は見つかりませんでしたので、結果から見ての想像の域を超
えてませんが。


> どうにか区別できるようにする方法はないでしょうか?

警告を出す方法はないかなど調べてみましたが、見つかりませんでした。

将来性のない VB.NET には見切りをつけて C# を使う・・・などというのはダメなんでしょう
ね。保守などで使わざるを得ないから使っているのでしょうから。

答えになってなくてすみません。どなたか VB.NET に詳しい人の回答を期待します。



ちなみに C# の場合は、if (v1 == Enum2.Square) とすると、

error CS0019: Operator '==' cannot be applied to operands of type 'Enum1' and 'Enum2'

というエラーになります。
[ 親 103344 / □ Tree ] 返信 編集キー/

▲[ 103344 ] / ▼[ 103375 ]
■103365 / 1階層)  Re[1]: 異なるEnumを=で比較できないようにする
□投稿者/ radian (161回)-(2024/10/16(Wed) 10:19:51)
2024/10/16(Wed) 10:20:24 編集(投稿者)

Strict Onでも警告やエラーならないなら、VB.NETではそういうものなのでしょう。
アナライザーでも自作したら検出出来るかもしれませんが、
異なるEnumの比較というケースがどの程度の頻度で発生するかを考えると
果たしてそこまでコストを掛ける価値があるかは疑問です。

https://github.com/dotnet/roslyn/blob/main/docs/wiki/How-To-Write-a-Visual-Basic-Analyzer-and-Code-Fix.md

[ 親 103344 / □ Tree ] 返信 編集キー/

▲[ 103365 ] / 返信無し
■103375 / 2階層)  Re[2]: 異なるEnumを=で比較できないようにする
□投稿者/ かば (2回)-(2024/10/16(Wed) 21:29:11)
みなさん回答ありがとうございます。
意外と難しいのですね。
納得しました。
解決済み
[ 親 103344 / □ Tree ] 返信 編集キー/


管理者用

- Child Tree -