Edit

Share via


Type.IsAssignableFrom(Type) Method

Definition

Determines whether an instance of a specified type c can be assigned to a variable of the current type.

C#
public virtual bool IsAssignableFrom(Type? c);
C#
public virtual bool IsAssignableFrom(Type c);

Parameters

c
Type

The type to compare with the current type.

Returns

true if any of the following conditions is true:

  • c and the current instance represent the same type.

  • c is derived either directly or indirectly from the current instance. c is derived directly from the current instance if it inherits from the current instance; c is derived indirectly from the current instance if it inherits from a succession of one or more classes that inherit from the current instance.

  • The current instance is an interface that c implements.

  • c is a generic type parameter, and the current instance represents one of the constraints of c.

  • c represents a value type, and the current instance represents Nullable<c> (Nullable(Of c) in Visual Basic).

false if none of these conditions are true, or if c is null.

Implements

Examples

The following example demonstrates the IsAssignableFrom method using defined classes, integer arrays, and generics.

C#
using System;
using System.Collections.Generic;
class Program
{
    public static void Main()
    {
            // Demonstrate classes:
            Console.WriteLine("Defined Classes:");
            Room room1 = new Room();
            Kitchen kitchen1 = new Kitchen();
            Bedroom bedroom1 = new Bedroom();
            Guestroom guestroom1 = new Guestroom();
            MasterBedroom masterbedroom1 = new MasterBedroom();

            Type room1Type = room1.GetType();
            Type kitchen1Type = kitchen1.GetType();
            Type bedroom1Type = bedroom1.GetType();
            Type guestroom1Type = guestroom1.GetType();
            Type masterbedroom1Type = masterbedroom1.GetType();

            Console.WriteLine("room assignable from kitchen: {0}", room1Type.IsAssignableFrom(kitchen1Type));
            Console.WriteLine("bedroom assignable from guestroom: {0}", bedroom1Type.IsAssignableFrom(guestroom1Type));
            Console.WriteLine("kitchen assignable from masterbedroom: {0}", kitchen1Type.IsAssignableFrom(masterbedroom1Type));

            // Demonstrate arrays:
            Console.WriteLine();
            Console.WriteLine("Integer arrays:");

            int[] array2 = new int[2];
            int[] array10 = new int[10];
            int[,] array22 = new int[2, 2];
            int[,] array24 = new int[2, 4];

            Type array2Type = array2.GetType();
            Type array10Type = array10.GetType();
            Type array22Type = array22.GetType();
            Type array24Type = array24.GetType();

            Console.WriteLine("int[2] assignable from int[10]: {0}", array2Type.IsAssignableFrom(array10Type));
            Console.WriteLine("int[2] assignable from int[2,4]: {0}", array2Type.IsAssignableFrom(array24Type));
            Console.WriteLine("int[2,4] assignable from int[2,2]: {0}", array24Type.IsAssignableFrom(array22Type));

            // Demonstrate generics:
            Console.WriteLine();
            Console.WriteLine("Generics:");

            // Note that "int?[]" is the same as "Nullable<int>[]"
            int?[] arrayNull = new int?[10];
            List<int> genIntList = new List<int>();
            List<Type> genTList = new List<Type>();

            Type arrayNullType = arrayNull.GetType();
            Type genIntListType = genIntList.GetType();
            Type genTListType = genTList.GetType();

            Console.WriteLine("int[10] assignable from int?[10]: {0}", array10Type.IsAssignableFrom(arrayNullType));
            Console.WriteLine("List<int> assignable from List<Type>: {0}", genIntListType.IsAssignableFrom(genTListType));
            Console.WriteLine("List<Type> assignable from List<int>: {0}", genTListType.IsAssignableFrom(genIntListType));

            Console.ReadLine();
    }
}
class Room
{
}

class Kitchen : Room
{
}

class Bedroom : Room
{
}

class Guestroom : Bedroom
{
}

class MasterBedroom : Bedroom
{
}

//This code example produces the following output:
//
// Defined Classes:
// room assignable from kitchen: True
// bedroom assignable from guestroom: True
// kitchen assignable from masterbedroom: False
//
// Integer arrays:
// int[2] assignable from int[10]: True
// int[2] assignable from int[2,4]: False
// int[2,4] assignable from int[2,2]: True
//
// Generics:
// int[10] assignable from int?[10]: False
// List<int> assignable from List<Type>: False
// List<Type> assignable from List<int>: False

In the following example, the current instance is a Type object that represents the Stream class. GenericWithConstraint is a generic type whose generic type parameter must be of type Stream. Passing its generic type parameter to the IsAssignableFrom method indicates that an instance of the generic type parameter can be assigned to an Stream object.

C#
using System;
using System.IO;

public class Example
{
   public static void Main()
   {
      Type t = typeof(Stream);
      Type genericT = typeof(GenericWithConstraint<>);
      Type genericParam = genericT.GetGenericArguments()[0];
      Console.WriteLine(t.IsAssignableFrom(genericParam));  
      // Displays True.
   }
}

public class GenericWithConstraint<T> where T : Stream
{}

Remarks

The IsAssignableFrom method can be used to determine whether an instance of c can be assigned to an instance of the current type, The method is most useful when you are handling objects whose types are not known at design time and allows for conditional assignment, as the following example shows.

C#
using System;
using System.Collections;

public class Example
{
   public static void Main()
   {
      Type t = typeof(IEnumerable);
      Type c = typeof(Array);
      
      IEnumerable instanceOfT;
      int[] instanceOfC = { 1, 2, 3, 4 };
      if (t.IsAssignableFrom(c))
         instanceOfT = instanceOfC;
  }
}

This method thus ensures that a line of code like the following will execute at runtime without throwing an InvalidCastException exception or a similar exception:

C#
instanceOfT = instanceOfC;

This method can be overridden by a derived class.

Note

A generic type definition is not assignable from a closed constructed type. That is, you cannot assign the closed constructed type MyGenericList<int> (MyGenericList(Of Integer) in Visual Basic) to a variable of type MyGenericList<T>.

If the c parameter is of type TypeBuilder, the result is based on the type that is to be built. The following code example demonstrates this using a built type named B.

C#
using System;
using System.Reflection;
using System.Reflection.Emit;

public class A
{}

public class Example
{
   public static void Main()
   {
      AppDomain domain = AppDomain.CurrentDomain;
      AssemblyName assemName = new AssemblyName();
      assemName.Name = "TempAssembly";

      // Define a dynamic assembly in the current application domain.
      AssemblyBuilder assemBuilder = domain.DefineDynamicAssembly(assemName,
                                            AssemblyBuilderAccess.Run);

      // Define a dynamic module in this assembly.
      ModuleBuilder moduleBuilder = assemBuilder.DefineDynamicModule("TempModule");

      TypeBuilder b1 = moduleBuilder.DefineType("B", TypeAttributes.Public, typeof(A));
      Console.WriteLine(typeof(A).IsAssignableFrom(b1));
   }
}
// The example displays the following output:
//        True

Applies to

Product Versions
.NET Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 2.0, 2.1