is (C# リファレンス)is (C# Reference)

オブジェクトに指定された型との互換性があるかどうかを確認するか、(C# 7.0 以降では) パターンとの比較によって式をテストします。Checks if an object is compatible with a given type, or (starting with C# 7.0) tests an expression against a pattern.

型の互換性に関するテストTesting for type compatibility

is キーワードを使用すると、実行時に型の互換性が評価されます。The is keyword evaluates type compatibility at runtime. これにより、オブジェクト インスタンスや式の結果を指定された型に変換できるかどうかが判定されます。It determines whether an object instance or the result of an expression can be converted to a specified type. 構文は次のとおりですIt has the syntax

   expr is type

ここで expr は何らかの型のインスタンスに評価される式、typeexpr の結果が変換される型の名前です。where expr is an expression that evaluates to an instance of some type, and type is the name of the type to which the result of expr is to be converted. is ステートメントでは、expr が null 以外の値で、式の評価によって得られるオブジェクトが type に変換できる場合に true、それ以外の場合に false が返されます。The is statement is true if expr is non-null and the object that results from evaluating the expression can be converted to type; otherwise, it returns false.

たとえば、次のコードでは objPerson 型のインスタンスにキャストできるかどうかが判定されます。For example, the following code determines if obj can be cast to an instance of the Person type:

if (obj is Person) {
   // Do something if obj is a Person.
}

is ステートメントは以下の場合に true となります。The is statement is true if:

  • exprtype と同じ型のインスタンスである。expr is an instance of the same type as type.

  • exprtype から派生した型のインスタンスである。expr is an instance of a type that derives from type. つまり、expr の結果を type のインスタンスにアップキャストできる。In other words, the result of expr can be upcast to an instance of type.

  • expr のコンパイル時の型が type の基底クラスであり、expr の実行時の型が type または type から派生した型である。expr has a compile-time type that is a base class of type, and expr has a runtime type that is type or is derived from type. 変数の "コンパイル時の型" とは、その変数の宣言で定義されている型です。The compile-time type of a variable is the variable's type as defined in its declaration. 変数の "実行時の型" とは、その変数に代入されているインスタンスの型です。The runtime type of a variable is the type of the instance that is assigned to that variable.

  • expr が、type インターフェイスを実装する型のインスタンスである。expr is an instance of a type that implements the type interface.

次の例は、変換ごとの is 式の評価が true となることを示しています。The following example shows that the is expression evaluates to true for each of these conversions.

using System;

public class Class1 : IFormatProvider
{
   public object GetFormat(Type t)
   {
      if (t.Equals(this.GetType()))      
         return this;
      return null;
   }
}

public class Class2 : Class1
{
   public int Value { get; set; }
}

public class Example
{
   public static void Main()
   {
      var cl1 = new Class1();
      Console.WriteLine(cl1 is IFormatProvider);
      Console.WriteLine(cl1 is Object);
      Console.WriteLine(cl1 is Class1);
      Console.WriteLine(cl1 is Class2); 
      Console.WriteLine();
 
      var cl2 = new Class2();
      Console.WriteLine(cl2 is IFormatProvider);
      Console.WriteLine(cl2 is Class2);
      Console.WriteLine(cl2 is Class1);
      Console.WriteLine();
      
      Class1 cl = cl2;
      Console.WriteLine(cl is Class1);
      Console.WriteLine(cl is Class2);
   }
}
// The example displays the following output:
//     True
//     True
//     True
//     False
//     
//     True
//     True
//     True
//     
//     True
//     True

式が常に true または false のいずれかになることが判明している場合は、is キーワードによってコンパイル時に警告が生成されます。The is keyword generates a compile-time warning if the expression is known to always be either true or false. 参照変換、ボックス変換、アンボックス変換のみが考慮され、ユーザー定義の変換や型の implicit および explicit 演算子によって定義された変換は無視されます。It only considers reference conversions, boxing conversions, and unboxing conversions; it does not consider user-defined conversions or conversions defined by a type's implicit and explicit operators. 次の例では、コンパイル時に変換結果が判明しているため、警告が生成されます。The following example generates warnings because the result of the conversion is known at compile-time. int から long および double への変換の is 式では、変換が implicit 演算子によって処理されるため、false が返される点に注意してください。Note that the is expression for conversions from int to long and double return false, since these conversions are handled by the implicit operator.

Console.WriteLine(3 is int);
Console.WriteLine();

int value = 6;
Console.WriteLine(value is long);
Console.WriteLine(value is double);
Console.WriteLine(value is object);
Console.WriteLine(value is ValueType);
Console.WriteLine(value is int);
// Compilation generates the following compiler warnings:
//   is2.cs(8,25): warning CS0183: The given expression is always of the provided ('int') type
//   is2.cs(12,25): warning CS0184: The given expression is never of the provided ('long') type
//   is2.cs(13,25): warning CS0184: The given expression is never of the provided ('double') type
//   is2.cs(14,25): warning CS0183: The given expression is always of the provided ('object') type
//   is2.cs(15,25): warning CS0183: The given expression is always of the provided ('ValueType') type
//   is2.cs(16,25): warning CS0183: The given expression is always of the provided ('int') type

expr には、匿名メソッドとラムダ式を除き、値を返すどのような式でも指定できます。expr can be any expression that returns a value, with the exception of anonymous methods and lambda expressions. 次の例では、is を使用してメソッド呼び出しの戻り値を評価しています。The following example uses is to evaluate the return value of a method call.

using System;

public class Example
{
   public static void Main()
   {
      double number1 = 12.63; 
      if (Math.Ceiling(number1) is double)
         Console.WriteLine("The expression returns a double.");
      else if (Math.Ceiling(number1) is decimal)    
         Console.WriteLine("The expression returns a decimal.");

      decimal number2 = 12.63m; 
      if (Math.Ceiling(number2) is double)
         Console.WriteLine("The expression returns a double.");
      else if (Math.Ceiling(number2) is decimal)    
         Console.WriteLine("The expression returns a decimal.");

   }
}
// The example displays the following output:
//     The expression returns a double.
//     The expression returns a decimal.

C# 7.0 以降では、型パターンによるパターン マッチングを使用することで、is ステートメントを用いたより簡潔なコードを記述できます。Starting with C# 7.0, you can use pattern matching with the type pattern to write more concise code that uses the is statement.

is を使用したパターン マッチングPattern matching with is

C# 7.0 以降では、is および switch ステートメントでパターン マッチングがサポートされています。Starting with C# 7.0, the is and switch statements support pattern matching. is キーワードでは、以下のパターンがサポートされています。The is keyword supports the following patterns:

  • 型パターン: 式を指定された型に変換できるかどうかをテストし、変換できる場合はその型の変数にキャストします。Type pattern, which tests whether an expression can be converted to a specified type and, if it can be, casts it to a variable of that type.

  • 定数パターン: 式の評価が指定された定数値になるかどうかをテストします。Constant pattern, which tests whether an expression evaluates to a specified constant value.

  • var パターン: 照合が常に成功し、式の値が新しいローカル変数にバインドされます。var pattern, a match that always succeeds and binds the value of an expression to a new local variable.

型パターン Type pattern

型パターンを使用してパターン マッチングを実行すると、式を指定された型に変換できるかどうかが is によってテストされ、変換できる場合はその型の変数にキャストされます。When using the type pattern to perform pattern matching, is tests whether an expression can be converted to a specified type and, if it can be, casts it to a variable of that type. is ステートメントのわかりやすい拡張機能であり、型の評価および変換を簡潔に記述できます。It is a straightforward extension of the is statement that enables concise type evaluation and conversion. is 型パターンの一般的な形式は次のとおりです。The general form of the is type pattern is:

   expr is type varname 

ここで expr は何らかの型のインスタンスに評価される式、typeexpr の結果が変換される型の名前、varnameis のテスト結果が true である場合に expr の結果が変換されるオブジェクトをそれぞれ表しています。where expr is an expression that evaluates to an instance of some type, type is the name of the type to which the result of expr is to be converted, and varname is the object to which the result of expr is converted if the is test is true.

exprnull ではなく、以下のいずれかの条件が true である場合に is 式は true となります。The is expression is true if expr is not null, and any of the following is true:

  • exprtype と同じ型のインスタンスである。expr is an instance of the same type as type.

  • exprtype から派生した型のインスタンスである。expr is an instance of a type that derives from type. つまり、expr の結果を type のインスタンスにアップキャストできる。In other words, the result of expr can be upcast to an instance of type.

  • expr のコンパイル時の型が type の基底クラスであり、expr の実行時の型が type または type から派生した型である。expr has a compile-time type that is a base class of type, and expr has a runtime type that is type or is derived from type. 変数の "コンパイル時の型" とは、その変数の宣言で定義されている型です。The compile-time type of a variable is the variable's type as defined in its declaration. 変数の "実行時の型" とは、その変数に代入されているインスタンスの型です。The runtime type of a variable is the type of the instance that is assigned to that variable.

  • expr が、type インターフェイスを実装する型のインスタンスである。expr is an instance of a type that implements the type interface.

exprtrueisif ステートメントと共に使用されている場合は varname への代入が行われ、そのローカル スコープは if ステートメント内に限定されます。If expr is true and is is used with an if statement, varname is assigned and has local scope within the if statement only.

次の例では、is 型のパターンを使用して、型 IComparable.CompareTo(Object) のメソッドの実装を提供します。The following example uses the is type pattern to provide the implementation of a type's IComparable.CompareTo(Object) method.

using System;

public class Employee : IComparable
{
    public String Name { get; set; }
    public int Id { get; set; }

    public int CompareTo(Object o)
    {
        if (o is Employee e)
        {
            return Name.CompareTo(e.Name);
        }
        throw new ArgumentException("o is not an Employee object.");
    }
}

パターン マッチングを使用しない場合、このコードは次のように記述できます。Without pattern matching, this code might be written as follows. 型パターン マッチングを使用することにより、変換結果が null であるかどうかをテストする必要がなくなるため、コードがよりコンパクトで読みやすくなります。The use of type pattern matching produces more compact, readable code by eliminating the need to test whether the result of a conversion is a null.

using System;

public class Employee : IComparable
{
    public String Name { get; set; }
    public int Id { get; set; }

    public int CompareTo(Object o)
    {
        var e = o as Employee;
        if (e == null)
        {
           throw new ArgumentException("o is not an Employee object.");
        }
        return Name.CompareTo(e.Name);
    }
}

is 型パターンを使用すると、値の型の種類を判定する場合によりコンパクトなコードを記述できます。The is type pattern also produces more compact code when determining the type of a value type. 次の例では、is 型パターンを使用し、オブジェクトが Person インスタンスか Dog インスタンスかを判定した後に適切なプロパティの値を表示しています。The following example uses the is type pattern to determine whether an object is a Person or a Dog instance before displaying the value of an appropriate property.

using System;

public class Example
{
   public static void Main()
   {
      Object o = new Person("Jane");
      ShowValue(o);
      
      o = new Dog("Alaskan Malamute");
      ShowValue(o);
   }

   public static void ShowValue(object o)
   {
      if (o is Person p) {
         Console.WriteLine(p.Name);
      }   
      else if (o is Dog d) {
         Console.WriteLine(d.Breed);
      }             
   }
}

public struct Person
{  
   public string Name { get; set; }
   
   public Person(string name) : this()
   {
      Name = name;
   }
}

public struct Dog
{
   public string Breed { get; set; }

   public Dog(string breedName) : this()
   {
      Breed = breedName;
   }
}
// The example displays the following output:
//	Jane
//	Alaskan Malamute

パターン マッチングを使用せずにこれと同等のコードを記述する場合は、明示的なキャストを含む代入処理を個別に行う必要があります。The equivalent code without pattern matching requires a separate assignment that includes an explicit cast.

using System;

public class Example
{
   public static void Main()
   {
      Object o = new Person("Jane");
      ShowValue(o);
      
      o = new Dog("Alaskan Malamute");
      ShowValue(o);
   }

   public static void ShowValue(object o)
   {
      if (o is Person) {
         Person p = (Person) o;
         Console.WriteLine(p.Name);
      }   
      else if (o is Dog) {
         Dog d = (Dog) o;
         Console.WriteLine(d.Breed);
      }             
   }
}

public struct Person
{  
   public string Name { get; set; }
   
   public Person(string name) : this()
   {
      Name = name;
   }
}

public struct Dog
{
   public string Breed { get; set; }

   public Dog(string breedName) : this()
   {
      Breed = breedName;
   }
}
// The example displays the following output:
//       Jane
//       Alaskan Malamute

定数パターン Constant pattern

定数パターンを使用してパターン マッチングを実行すると、式が指定された定数と等しいかどうかが is によってテストされます。When performing pattern matching with the constant pattern, is tests whether an expression equals a specified constant. C# 6 以前のバージョンでの定数パターンは switch ステートメントでサポートされています。In C# 6 and earlier versions, the constant pattern is supported by the switch statement. C# 7.0 以降では、is ステートメントでもサポートされています。Starting with C# 7.0, it is supported by the is statement as well. 構文は次のとおりです。Its syntax is:

   expr is constant

ここで expr は評価する式、constant はテストする値を表しています。where expr is the expression to evaluate, and constant is the value to test for. constant には以下のいずれかの定数式を指定できます。constant can be any of the following constant expressions:

  • リテラル値。A literal value.

  • 宣言された const 変数の名前。The name of a declared const variable.

  • 列挙定数。An enumeration constant.

定数式は以下のように評価されます。The constant expression is evaluated as follows:

  • exprconstant が整数型の場合、式から true が返されるかどうか (つまり、expr == constant であるかどうか) が C# の等値演算子によって判定されます。If expr and constant are integral types, the C# equality operator determines whether the expression returns true (that is, whether expr == constant).

  • それ以外の場合、式の値は静的 Object.Equals(expr, constant) メソッドの呼び出しによって判定されます。Otherwise, the value of the expression is determined by a call to the static Object.Equals(expr, constant) method.

次の例では、型パターンと定数パターンを組み合わせてオブジェクトが Dice インスタンスであるかどうかをテストし、そうである場合はサイコロ振り操作の値が 6 であるかどうかをテストします。The following example combines the type and constant patterns to test whether an object is a Dice instance and, if it is, to determine whether the value of a dice roll is 6.

using System;

public class Dice
{
    Random rnd = new Random();
    public Dice()
    {

    }
    public int Roll()
    {
        return rnd.Next(1, 7); 
    }
}

class Program
{
    static void Main(string[] args)
    {
        var d1 = new Dice();
        ShowValue(d1);
    }

    private static void ShowValue(object o)
    {
        const int HIGH_ROLL = 6;

        if (o is Dice d && d.Roll() is HIGH_ROLL)
            Console.WriteLine($"The value is {HIGH_ROLL}!");
        else
            Console.WriteLine($"The dice roll is not a {HIGH_ROLL}!");
     }
}
// The example displays output like the following:
//      The value is 6!

定数パターンを使用して、null のチェックを実行できます。Checking for null can be performed using the constant pattern. is ステートメントで null キーワードがサポートされています。The null keyword is supported by the is statement. 構文は次のとおりです。Its syntax is:

   expr is null

null チェックの比較を示す例を次に示します。The following example shows a comparison of null checks:

using System;

class Program
{
    static void Main(string[] args)
    {
        object o = null;

        if (o is null)
        {
            Console.WriteLine("o does not have a value");
        }
        else
        {
            Console.WriteLine($"o is {o}");
        }
        
        int? x = 10;

        if (x is null)
        {
            Console.WriteLine("x does not have a value");
        }
        else
        {
            Console.WriteLine($"x is {x.Value}");
        }
        
        // 'null' check comparison
        Console.WriteLine($"'is' constant pattern 'null' check result : { o is null }");
        Console.WriteLine($"object.ReferenceEquals 'null' check result : { object.ReferenceEquals(o, null) }");
        Console.WriteLine($"Equality operator (==) 'null' check result : { o == null }");
    }

    // The example displays the following output:
    // o does not have a value
    // x is 10
    // 'is' constant pattern 'null' check result : True
    // object.ReferenceEquals 'null' check result : True
    // Equality operator (==) 'null' check result : True
}

var パターン var pattern

var パターンによるパターン マッチは常に成功します。A pattern match with the var pattern always succeeds. 構文は次のとおりですIts syntax is

   expr is var varname

ここで expr の値は常に varname というローカル変数に代入されます。where the value of expr is always assigned to a local variable named varname. varnameexpr と同じ型の静的変数です。varname is a static variable of the same type as expr. 次の例では、var パターンを使用して式を obj という変数に代入しています。The following example uses the var pattern to assign an expression to a variable named obj. その後、obj の値と型が表示されます。It then displays the value and the type of obj.

using System;

class Program
{
    static void Main()
   {
      object[] items = { new Book("The Tempest"), new Person("John") };
      foreach (var item in items) {
        if (item is var obj)
          Console.WriteLine($"Type: {obj.GetType().Name}, Value: {obj}"); 
      }
   }
}

class Book
{
    public Book(string title) 
    {
       Title = title;    
    }

    public string Title { get; set; }

    public override string ToString()
    {
       return Title;
    }
}

class Person
{
   public Person(string name)
   {
      Name = name;
   }

   public string Name 
   { get; set; }

   public override string ToString()
   {
      return Name;
   }
}
// The example displays the following output:
//       Type: Book, Value: The Tempest
//       Type: Person, Value: John

exprnull である場合も is 式は true となり、nullvarname に代入される点に注意してください。Note that if expr is null, the is expression still is true and assigns null to varname.

C# 言語仕様C# Language Specification

詳細については、「C# 言語の仕様」を参照してください。For more information, see the C# Language Specification. 言語仕様は、C# の構文と使用法に関する信頼性のある情報源です。The language specification is the definitive source for C# syntax and usage.

関連項目See also