これが機能する理由
if (mycontrol.GetType() == typeof(TextBox))
{}
そしてこれはしませんか?
Type tp = typeof(mycontrol);
しかし、これは機能します
Type tp = mycontrol.GetType();
私自身is
、タイプのチェックに演算子を使用していますがtypeof()
、GetType()
いつどこで使用するGetType()
かtypeof()
?
typeof
は、コンパイル時に既知の型(または少なくともジェネリック型パラメーター)を取得するための演算子です。のオペランドは、typeof
常に型または型パラメーターの名前です。値を持つ式(変数など)は使用できません。詳細については、C#言語仕様を参照してください。
GetType()
オブジェクトの実行時タイプを取得するために、個々のオブジェクトに対して呼び出すメソッドです。
(サブクラスのインスタンスではなく)のインスタンスのみが必要な場合を除いて、通常は次のものを使用することに注意してください。TextBox
if (myControl is TextBox)
{
// Whatever
}
または
TextBox tb = myControl as TextBox;
if (tb != null)
{
// Use tb
}
typeof
コンパイル時に既知の型またはジェネリック型パラメーターの名前に適用されます(文字列ではなく識別子として指定されます)。GetType
実行時にオブジェクトに対して呼び出されます。System.Type
どちらの場合も、結果は型に関するメタ情報を含む型のオブジェクトになります。
コンパイル時と実行時の型が等しい例
string s = "hello";
Type t1 = typeof(string);
Type t2 = s.GetType();
t1 == t2 ==> true
コンパイル時と実行時の型が異なる例
object obj = "hello";
Type t1 = typeof(object); // ==> object
Type t2 = obj.GetType(); // ==> string!
t1 == t2 ==> false
つまり、変数のコンパイル時の型(静的型)は、でobj
参照されるオブジェクトの実行時型と同じではありませんobj
。
テストタイプ
mycontrol
ただし、それがであるかどうかだけを知りたい場合は、TextBox
単にテストすることができます
if (mycontrol is TextBox)
これは完全に同等ではないことに注意してください
if (mycontrol.GetType() == typeof(TextBox))
mycontrol
から派生した型を持つ可能性があるためTextBox
です。その場合、最初の比較で結果が得られtrue
、2番目の比較でfalse
!から派生したコントロールは、持っているTextBox
すべてのものを継承しTextBox
、おそらくそれをさらに追加し、したがって、との割り当て互換性があるため、最初の簡単なバリアントはほとんどの場合OKですTextBox
。
public class MySpecializedTextBox : TextBox
{
}
MySpecializedTextBox specialized = new MySpecializedTextBox();
if (specialized is TextBox) ==> true
if (specialized.GetType() == typeof(TextBox)) ==> false
鋳造
次のテストの後にキャストが続き、Tがnull許容である場合..。
if (obj is T) {
T x = (T)obj; // The casting tests, whether obj is T again!
...
}
...次のように変更できます...
T x = obj as T;
if (x != null) {
...
}
値が特定のタイプであるかどうかのテストとキャスト(これには同じテストが再度含まれます)は、長い継承チェーンでは両方とも時間がかかる可能性があります。as
演算子に続いてのテストを使用するnull
と、パフォーマンスが向上します。
C#7.0以降では、パターンマッチングを使用してコードを簡略化できます。
if (obj is T t) {
// t is a variable of type T having a non-null value.
...
}
ところで:これは値型でも機能します。テストと開梱に非常に便利です。null許容値タイプをテストできないことに注意してください。
if (o is int? ni) ===> does NOT compile!
これは、値がであるか、であるためnull
ですint
。これは、次の場合int? o
と同様に機能しobject o = new Nullable<int>(x);
ます。
if (o is int i) ===> OK!
Nullable<T>.Value
プロパティにアクセスする必要がないので、私はそれが好きです。
is
キーワードを使用する方が簡単な場合があります:
if (mycontrol is TextBox)