Type.IsAssignableFrom(Type) Metodo

Definizione

Determina se è possibile assegnare un'istanza di un tipo c specificato a una variabile del tipo corrente.

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

Parametri

c
Type

Tipo da confrontare con il tipo corrente.

Restituisce

true se una o più delle condizioni seguenti sono vere:

  • c e l'istanza corrente rappresentano lo stesso tipo.

  • c deriva direttamente o indirettamente dall'istanza corrente. c deriva direttamente dall'istanza corrente se eredita dall'istanza corrente. c deriva indirettamente dall'istanza corrente se eredita da una successione di una o più classi che ereditano dall'istanza corrente.

  • L'istanza corrente è un'interfaccia che c implementa.

  • c è un parametro di tipo generico e l'istanza corrente rappresenta uno dei vincoli di c.

  • c rappresenta un tipo di valore e l'istanza corrente rappresenta Nullable<c> (Nullable(Of c) in Visual Basic).

false se non viene soddisfatta nessuna di queste condizioni oppure se c è null.

Implementazioni

Esempio

Nell'esempio seguente viene illustrato il IsAssignableFrom metodo usando classi definite, matrici integer e 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

Nell'esempio seguente, l'istanza corrente è un oggetto Type che rappresenta la classe Stream. GenericWithConstraint è un tipo generico il cui parametro di tipo generico deve essere di tipo Stream. Passando il parametro di tipo generico al metodo indica che un'istanza IsAssignableFrom del parametro di tipo generico può essere assegnata a un Stream oggetto.

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

Commenti

Il metodo può essere usato per determinare se è possibile assegnare un'istanza di a un'istanza del tipo corrente, il IsAssignableFrom metodo è più utile quando si gestiscono oggetti i cui tipi non sono noti in fase di c progettazione e consentono l'assegnazione condizionale, come illustrato nell'esempio seguente.

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

Questo metodo garantisce quindi che una riga di codice simile alla seguente verrà eseguita in fase di esecuzione senza generare un'eccezione InvalidCastException o un'eccezione simile:

C#
instanceOfT = instanceOfC;

Questo metodo può essere sottoposto a override da una classe derivata.

Nota

Una definizione di tipo generica non è assegnabile da un tipo costruito chiuso. Ovvero, non è possibile assegnare il tipo MyGenericList<int> costruito chiuso (MyGenericList(Of Integer) in Visual Basic) a una variabile di tipo MyGenericList<T>.

Se il parametro è di tipo TypeBuilder, il c risultato è basato sul tipo che deve essere compilato. Nell'esempio di codice seguente viene illustrato questo uso di un tipo compilato denominato 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

Si applica a

Prodotto Versioni
.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