たまに「じゃんぬねっと」が生存確認をする日記

役員より労働者の方が楽だと思う

ホーム 連絡をする 同期する ( RSS 2.0 ) Login
投稿数  984  : 記事  4  : コメント  38837  : トラックバック  277

ニュース

My Website

初心者向けのサイトです。

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

最近のできごと

低学歴の IT エンジニア兼管理職です。ずっとリモートワーク中。

駆け出しはブラック企業で低年収でしたが、転職を繰り返して年収は 5 倍以上になりました。

年収はこれ以上増えても幸せ指数は増えませんので、趣味の時間を増やすため早期の半リタイアを考えています。

最高の配偶者、可愛い娘、ハンサムな息子と幸せな日々を送っています。

Sponsored Link1

Sponsored Link2

Archive

書庫

型を比較、または検証する場合、String で評価しない方が良いです。
型名での比較は、型を評価しているわけではなく、文字列を評価しているに過ぎません。

いくつかの言語で、その例を紹介します。

C#

    if (obj.GetType().Name == "Label") {
        MessageBox.Show("Label です");
    }

VB.NET

    Select Case obj.GetType().Name
        Case "Label"
            MessageBox.Show("Label です");
        Case "TextBox"
            MessageBox.Show("TextBox です");
    End Select

VB [VB6]

    Select Case TypeName(obj)
        Case "Label"
            Call MsgBox("Label です")
        Case "TextBox"
            Call MsgBox("TextBox です")
    End Select

これらは、文字列の検証に過ぎず、型に関して「コンパイル解決」していません。
実行時まで、型自体の有効性がわからないわけです。(存在しないかもしれない、typo しているかもしれない)

また、型の検証は、互換性を見るために行うことが殆どでしょう。
文字列の比較では、同一の "型名" であるかどうかしか検証できません。
継承階層上で互換性のある型の検証ができません。(TextBox は TextBoxBase と互換性がある)
また、(普通はないですが) たまたま同名の型で、互換性がなかった場合はバグになります。

C# では is を、VB では TypeOf ~ Is を、J# では instanceof などを使うようにしましょう。
(C# については、as、typeof、VB については、GetType 演算子についても見るようにしてください)

C#

    if (obj is Label) {
        MessageBox.Show("Label と互換性のあるクラスです");
    }

VB

    If TypeOf obj Is Label Then
        MessageBox.Show("Label と互換性のあるクラスです");
    End If

J# [Java]

    if (obj instanceof Label) {
        MessageBox.Show("Label と互換性のあるクラスです");
    }

もっとも、型の検証を避けるような仕様 / 実装にするのが賢明です。
(ポリモーフィズムという観点で見ると、微妙な言い回しですが)

投稿日時 : 2006年6月23日 11:32

コメント

# re: 型を比較検証する場合 2006/06/23 12:54 囚人
>もっとも、型の検証を避けるような仕様 / 実装にするのが賢明です。

ダウンキャストをしなければならない時は結構使ったりしますね。is よりも as の方をよく使ったりします(C#)

# re: 型を比較検証する場合 2006/06/23 13:00 じゃんぬ
「ポリモーフィズム」という観点で見ると、微妙な言い回しでしたね。
それすら避けるようにすべきという方が、わんくま同盟にはいらっしゃいますけどw

# re: 型を比較検証する場合 2006/06/23 13:11 青柳 臣一
C# の is 演算子は変換可能であるか (キャスト可能であるか) を返しますので、気をつけないといけない場合もありますね。obj が Label (Control の派生型) だとすると obj is Control も真になります。

obj.GetType().Name == "Label" と同じことを文字列を使わないでやる場合は、obj.GetType() == typeof(Label) とかにすればいいのかな。

# re: 型を比較検証する場合 2006/06/23 14:19 買太郎
>ダウンキャストをしなければならない時は結構使ったりしますね。

画面に含まれてるすべてのコントロールをループ処理して、コントロール毎に基本設定する時に、よくやりますね。

昔は、文字列でやってたけど、今は、ちゃんと型を考えて実装するようにしてます。

# re: 型を比較検証する場合 2006/06/23 16:09 NyaRuRu
C# の is は CLR の Type.IsAssignableFrom と矛盾する結果を返すこともありますけどね.
(CLR 的には互換性があっても,C# の範囲では互換性が無いことになっている)

DayOfWeek[] enumArray = new DayOfWeek[]{DayOfWeek.Monday};
int[] intArray1 = (int[]) enumArray; // コンパイルエラー
int[] intArray2 = (int[]) (object) enumArray; // 成功
bool ret1 = enumArray is int[]; // コンパイル時評価で false が入る
bool ret2 = (object)enumArray is int[]; // 実行時評価で true が入る


# re: 型を比較検証する場合 2006/06/23 16:14 じゃんぬ
Σ(;゚Д゚)

# re: 型を比較検証する場合 2006/06/23 19:14 R・田中一郎
>もっとも、型の検証を避けるような仕様 / 実装にするのが賢明です。

これは、例えば、TextBox の場合なら ~、と言う考え方をすべきではないということでしょうか?


# re: 型を比較検証する場合 2006/06/24 10:26 通りすがーり
そうでしょう。.NETはポリモーフィズムマンセーじゃないし。
とかいいつつ、インターフェイスを実装しているかレベルで使うことがほとんどですがw
まったくなしは難しくとも少ないに越したことはないですしね。実装の問題というより仕様の問題である場合も多いし。
何と言ったらいいかわかんないけど、使ってもいいけど使いどころが間違ってる例が多いというか・・うまく言えない。

# re: 型を比較検証する場合 2006/06/25 23:30 黒龍
型の検証を避けるのは厳しいです;_;

僕自身は型検証がいるケース(主にインタフェースを実装しているか?もしくは派生クラスか?)は大抵isで型検証しますが完全一致させたい場合はTypeをとってからFullnameで検証してますね。

>(CLR 的には互換性があっても,C# の範囲では互換性が無いことになっている)
大変興味深い内容なんですがこのケースではEnumとintの間で明示的キャストが必要というC#の言語仕様に引っかかるためという認識でよろしいでしょうか?

# re: 型を比較検証する場合 2006/06/26 11:07 NyaRuRu
>大変興味深い内容なんですがこのケースではEnumとintの間で明示的キャストが必要というC#の言語仕様に引っかかるためという認識でよろしいでしょうか?

どちらかというと,Enum 配列に関する CLR の特殊ルールを全てサポートしているわけではない,というのが大きいんじゃないですかね.

http://download.microsoft.com/download/6/8/8/68863d89-d35d-4bc5-8a1c-7e0a02e1881e/Partition_III_CIL.zip


2 4.3 castclass ? cast an object to a class

1. Arrays inherit from System.Array
2. If Foo can be cast to Bar, then Foo[] can be cast to Bar[]
3. For the purposes of 2., enums are treated as their undertlying type: thus E1[] can cast to E2[] if E1 and E2 share an underlying type If obj is null, castclass succeeds and returns null. This behavior differs from isInst.

C# はこのうち 1 と 2 はサポートしますが,3 は「存在しないもの」として振る舞います.

このような例は他にもいくつかありますが,長いので以下を参照してください.
http://forums.microsoft.com/msdn/showpost.aspx?postid=212982&siteid=1#212982

# re: 型を比較検証する場合 2006/06/26 12:00 黒龍
勉強になります

# re: 型を比較検証する場合 2006/06/26 13:11 NyaRuRu
あー,変なところでくっついてる.

3. For the purposes of 2., enums are treated as their undertlying type: thus E1[] can cast to E2[] if E1 and E2 share an underlying type


If obj is null, castclass succeeds and returns null. This behavior differs from isInst.

null 云々の部分は 3 とは別です.念のため.


# RxPLJzcaKkjvjByPA 2022/04/19 10:59 johnansaz
http://imrdsoacha.gov.co/silvitra-120mg-qrms

Post Feedback

タイトル
名前
Url:
コメント: