Ler em inglês

Compartilhar via


Type.IsAssignableFrom(Type) Método

Definição

Determina se uma instância de um tipo c especificado pode ser atribuída a uma variável do tipo atual.

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

Parâmetros

c
Type

O tipo a ser comparado com o tipo atual.

Retornos

Boolean

true se qualquer uma das seguintes condições for verdadeira:

  • c e a instância atual representam o mesmo tipo.

  • c é derivado direta ou indiretamente da instância atual. c será derivado diretamente da instância atual se herdar da instância atual; c será derivado indiretamente da instância atual se herdar de uma sucessão de uma ou mais classes que herdam da instância atual.

  • A instância atual é uma interface implementada por c.

  • c é um parâmetro de tipo genérico, e a instância atual representa uma das restrições de c.

  • c representa um tipo de valor e a instância atual representa Nullable<c> (Nullable(Of c) no Visual Basic).

false se nenhuma dessas condições for verdadeira, ou se c for null.

Implementações

Exemplos

O exemplo a seguir demonstra o IsAssignableFrom método usando classes definidas, matrizes de inteiros e genéricos.

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:
//
// Defned 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

No exemplo a seguir, a instância atual é um objeto Type que representa a classe Stream. GenericWithConstraint é um tipo genérico cujo parâmetro de tipo genérico deve ser do tipo Stream . Passar seu parâmetro de tipo genérico para o IsAssignableFrom método indica que uma instância do parâmetro de tipo genérico pode ser atribuída a um Stream objeto.

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
{}

Comentários

O IsAssignableFrom método pode ser usado para determinar se uma instância de c pode ser atribuída a uma instância do tipo atual, o método é mais útil quando você está manipulando objetos cujos tipos não são conhecidos em tempo de design e permite a atribuição condicional, como mostra o exemplo a seguir.

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;
  }
}

Assim, esse método garante que uma linha de código como a seguinte será executada no tempo de execução sem gerar uma InvalidCastException exceção ou uma exceção semelhante:

C#
instanceOfT = instanceOfC;

Este método pode ser substituído por uma classe derivada.

Observação

Uma definição de tipo genérico não pode ser atribuída a partir de um tipo construído fechado. ou seja, você não pode atribuir o tipo construído fechado MyGenericList<int> ( MyGenericList(Of Integer) em Visual Basic) a uma variável do tipo MyGenericList<T> .

Se o c parâmetro for do tipo TypeBuilder , o resultado será baseado no tipo que deve ser compilado. O exemplo de código a seguir demonstra isso usando um tipo interno chamado 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

Aplica-se a

Produto Versões
.NET Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7
.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
.NET Standard 2.0, 2.1