Leer en inglés

Compartir a través de


Type.IsAssignableFrom(Type) Método

Definición

Determina si se puede asignar una instancia de un tipo c especificado a una variable del tipo actual.

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

Parámetros

c
Type

Tipo que se va a comparar con el tipo actual.

Devoluciones

true si alguna de las condiciones siguientes es "true":

  • c y la instancia actual representan el mismo tipo.

  • c se deriva de forma directa o indirecta de la instancia actual. c se deriva directamente de la instancia actual si se hereda de la instancia actual, mientras que c se deriva indirectamente de la instancia actual si se hereda de una sucesión de una o varias clases que se heredan de la instancia actual.

  • La instancia actual es una interfaz que c implementa.

  • c es un parámetro de tipo genérico y la instancia actual representa una de las restricciones de c.

  • c representa un tipo de valor y la instancia actual representa Nullable<c> (Nullable(Of c) en Visual Basic).

Es false si ninguna de estas condiciones son true o si c es null.

Implementaciones

Ejemplos

En el ejemplo siguiente se muestra el IsAssignableFrom método mediante clases definidas, matrices de enteros y 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:
//
// 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

En el ejemplo siguiente, la instancia actual es un objeto Type que representa la clase Stream. GenericWithConstraint es un tipo genérico cuyo parámetro de tipo genérico debe ser de tipo Stream. Pasar su parámetro de tipo genérico al IsAssignableFrom método indica que se puede asignar una instancia del parámetro de tipo genérico a un 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
{}

Comentarios

El método se puede usar para determinar si una instancia de c se puede asignar a una instancia del tipo actual. El IsAssignableFrom método es más útil cuando se controlan los objetos cuyos tipos no se conocen en tiempo de diseño y permite la asignación condicional, como se muestra en el ejemplo siguiente.

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

Este método garantiza así que una línea de código como la siguiente se ejecutará en tiempo de ejecución sin iniciar una InvalidCastException excepción o una excepción similar:

C#
instanceOfT = instanceOfC;

Este método se puede invalidar mediante una clase derivada.

Nota

Una definición de tipo genérico no se puede asignar a partir de un tipo construido cerrado. Es decir, no se puede asignar el tipo MyGenericList<int> construido cerrado (MyGenericList(Of Integer) en Visual Basic) a una variable de tipo MyGenericList<T>.

Si el c parámetro es de tipo TypeBuilder, el resultado se basa en el tipo que se va a compilar. En el ejemplo de código siguiente se muestra esto mediante un tipo compilado denominado 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

Se aplica a

Producto Versiones
.NET Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9, 10
.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