Type.IsAssignableFrom(Type) 方法

定义

确定指定类型 c 的实例是否能分配给当前类型的变量。

public:
 virtual bool IsAssignableFrom(Type ^ c);
public virtual bool IsAssignableFrom (Type? c);
public virtual bool IsAssignableFrom (Type c);
abstract member IsAssignableFrom : Type -> bool
override this.IsAssignableFrom : Type -> bool
Public Overridable Function IsAssignableFrom (c As Type) As Boolean

参数

c
Type

要与当前类型进行比较的类型。

返回

如果满足下列任一条件,则为 true

  • c 和当前实例表示相同类型。

  • c 是从当前实例直接或间接派生的。 如果继承于当前实例,则 c 是从当前实例直接派生的;如果继承于从当前实例继承的接连一个或多个类,则 c 是从当前实例间接派生的。

  • 当前实例是实现 的 c 接口。

  • c 是一个泛型类型参数,并且当前实例表示 c 的约束之一。

  • c 表示值类型,当前实例表示 Nullable<c> Visual Basic) Nullable(Of c) 中的 (。

如果不满足上述任何一个条件或者 cfalse,则为 null

实现

示例

下面的示例演示 IsAssignableFrom 了使用已定义的类、整数数组和泛型的方法。

using namespace System;
using namespace System::Collections::Generic;

ref class Room
{
};

ref class Kitchen : Room
{
};

ref class Bedroom : Room
{
};

ref class Guestroom : Bedroom
{
};

ref class MasterBedroom : Bedroom
{
};

ref class Program
{
public:
    static void Main()
    {
            // Demonstrate classes:
            Console::WriteLine("Defined Classes:");
            Room^ room1 = gcnew Room();
            Kitchen^ kitchen1 = gcnew Kitchen();
            Bedroom^ bedroom1 = gcnew Bedroom();
            Guestroom^ guestroom1 = gcnew Guestroom();
            MasterBedroom^ masterbedroom1 = gcnew 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:");
            array<Int32>^ array2 = gcnew array<Int32>(2);
            array<Int32>^ array10 = gcnew array<Int32>(10);
            array<Int32, 2>^ array22 = gcnew array<Int32, 2>(2, 2);
            array<Int32, 2>^ array24 = gcnew array<Int32, 2>(2, 4);

            Type^ array2Type = array2->GetType();
            Type^ array10Type = array10->GetType();
            Type^ array22Type = array22->GetType();
            Type^ array24Type = array24->GetType();

            Console::WriteLine("Int32[2] assignable from Int32[10]: {0}", array2Type->IsAssignableFrom(array10Type));
            Console::WriteLine("Int32[2] assignable from Int32[2,4]: {0}", array2Type->IsAssignableFrom(array24Type));
            Console::WriteLine("Int32[2,4] assignable from Int32[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];
            array<Nullable^>^ arrayNull = gcnew array<Nullable^>(10);
            List<Int32>^ genIntList = gcnew List<Int32>();
            List<Type^>^ genTList = gcnew List<Type^>();

            Type^ arrayNullType = arrayNull->GetType();
            Type^ genIntListType = genIntList->GetType();
            Type^ genTListType = genTList->GetType();

            Console::WriteLine("Int32[10] assignable from Nullable[10]: {0}", array10Type->IsAssignableFrom(arrayNullType));
            Console::WriteLine("List<Int32> assignable from List<Type^>: {0}", genIntListType->IsAssignableFrom(genTListType));
            Console::WriteLine("List<Type^> assignable from List<Int32>: {0}", genTListType->IsAssignableFrom(genIntListType));

            Console::ReadLine();
    }
};

int main()
{
    Program::Main();
}

//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:
// Int32[2] assignable from Int32[10]: True
// Int32[2] assignable from Int32[2,4]: False
// Int32[2,4] assignable from Int32[2,2]: True
//
// Generics:
// Int32[10] assignable from Nullable[10]: False
// List<Int32> assignable from List<Type^>: False
// List<Type^> assignable from List<Int32>: False
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
open System

type Room() = class end

type Kitchen() = inherit Room()

type Bedroom() = inherit Room()

type Guestroom() = inherit Bedroom()

type MasterBedroom() = inherit Bedroom()

// Demonstrate classes:
printfn "Defined Classes:"
let room1 = Room()
let kitchen1 = Kitchen()
let bedroom1 = Bedroom()
let guestroom1 = Guestroom()
let masterbedroom1 = MasterBedroom()

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

printfn $"room assignable from kitchen: {room1Type.IsAssignableFrom kitchen1Type}"
printfn $"bedroom assignable from guestroom: {bedroom1Type.IsAssignableFrom guestroom1Type}"
printfn $"kitchen assignable from masterbedroom: {kitchen1Type.IsAssignableFrom masterbedroom1Type}"

// Demonstrate arrays:
printfn "\nInteger arrays:"

let array2 = Array.zeroCreate<int> 2
let array10 = Array.zeroCreate<int> 10
let array22 = Array2D.zeroCreate<int> 2 2
let array24 = Array2D.zeroCreate<int> 2 4

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

printfn $"int[2] assignable from int[10]: {array2Type.IsAssignableFrom array10Type}"
printfn $"int[2] assignable from int[2,4]: {array2Type.IsAssignableFrom array24Type}"
printfn $"int[2,4] assignable from int[2,2]: {array24Type.IsAssignableFrom array22Type}"

// Demonstrate generics:
printfn "\nGenerics:"

let arrayNull = Array.zeroCreate<Nullable<int>> 10
let genIntList = ResizeArray<int>()
let genTList = ResizeArray<Type>()

let arrayNullType = arrayNull.GetType()
let genIntListType = genIntList.GetType()
let genTListType = genTList.GetType()

printfn $"int[10] assignable from int?[10]: {array10Type.IsAssignableFrom arrayNullType}"
printfn $"List<int> assignable from List<Type>: {genIntListType.IsAssignableFrom genTListType}"
printfn $"List<Type> assignable from List<int>: {genTListType.IsAssignableFrom genIntListType}"

//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
Imports System.Collections.Generic

Module Example
    Public Sub Main()
        Console.WriteLine("Defined Classes:")
        Dim room1 As New Room()
        Dim kitchen1 As New Kitchen()
        Dim bedroom1 As New Bedroom()
        Dim guestroom1 As New Guestroom()
        Dim masterbedroom1 As New MasterBedroom()

        Dim room1Type As Type = room1.GetType()
        Dim kitchen1Type As Type = kitchen1.GetType()
        Dim bedroom1Type As Type = bedroom1.GetType()
        Dim guestroom1Type As Type = guestroom1.GetType()
        Dim masterbedroom1Type As Type = 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:")

        Dim array10(10) As Integer
        Dim array2(2) As Integer
        Dim array22(2, 2) As Integer
        Dim array24(2, 4) As Integer

        Dim array10Type As Type = array10.GetType
        Dim array2Type As Type = array2.GetType
        Dim array22Type As Type = array22.GetType
        Dim array24Type As Type = array24.GetType

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

        ' Demonstrate generics:
        Console.WriteLine()
        Console.WriteLine("Generics:")

        Dim arrayNull(10) As Nullable(Of Integer)
        Dim genIntList As New List(Of Integer)
        Dim genTList As New List(Of Type)

        Dim arrayNullType As Type = arrayNull.GetType
        Dim genIntListType As Type = genIntList.GetType
        Dim genTListType As Type = genTList.GetType

        Console.WriteLine("Integer(10) assignable from Nullable(Of Integer)(10): {0}", array10Type.IsAssignableFrom(arrayNullType))
        Console.WriteLine("List(Of Integer) assignable from List(Of Type): {0}", genIntListType.IsAssignableFrom(genTListType))
        Console.WriteLine("List(Of Type) assignable from List(Of Integer): {0}", genTListType.IsAssignableFrom(genIntListType))
        Console.ReadLine()
    End Sub
End Module

Class Room
End Class

Class Kitchen : Inherits Room
End Class

Class Bedroom : Inherits Room
End Class

Class Guestroom : Inherits Bedroom
End Class

Class MasterBedroom : Inherits Bedroom
End Class
' The example displays the following output:
'    Defined Classes:
'    room assignable from kitchen: True
'    bedroom assignable from guestroom: True
'    kitchen assignable from masterbedroom: False
'
'    Integer arrays:
'    Integer(2) assignable from Integer(10): True
'    Integer(2) assignable from Integer(2,4): False
'    Integer(2,4) assignable from Integer(2,2): True
'
'    Generics:
'    Integer(10) assignable from Nullable(Of Integer)(10): False
'    List(Of Integer) assignable from List(Of Type): False
'    List(Of Type) assignable from List(Of Integer): False

在以下示例中,当前实例是表示 Stream 类的 Type 对象。 GenericWithConstraint 是泛型类型,其泛型类型参数必须为 类型 Stream。 将其泛型类型参数传递给 IsAssignableFrom 方法指示可以将泛型类型参数的实例分配给对象 Stream

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
{}
open System.IO

type GenericWithConstraint<'T when 'T :> Stream>() = class end

let t = typeof<Stream>
let genericT = typeof<GenericWithConstraint<_>>.GetGenericTypeDefinition()
let genericParam = genericT.GetGenericArguments()[0]
printfn $"{t.IsAssignableFrom genericParam}"
// Displays True.
Imports System.IO

Module Example
   Public Sub Main()
      Dim t As Type = GetType(Stream)
      Dim genericT As Type = GetType(GenericWithConstraint(Of ))
      Dim genericParam As Type = genericT.GetGenericArguments()(0)
      Console.WriteLine(t.IsAssignableFrom(genericParam))  
      ' Displays True.
   End Sub
End Module

Public Class GenericWithConstraint(Of T As Stream)
End Class

注解

方法 IsAssignableFrom 可用于确定是否可以将 的 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;
  }
}
open System
open System.Collections

let t = typeof<IEnumerable>
let c = typeof<Array>

let mutable instanceOfT = Unchecked.defaultof<IEnumerable>
let instanceOfC = [| 1; 2; 3; 4 |]
if t.IsAssignableFrom c then
    instanceOfT <- instanceOfC
Imports System.Collections

Module Example
   Public Sub Main()
      Dim t As Type = GetType(IEnumerable)
      Dim c As Type = GetType(Array)
      
      Dim instanceOfT As IEnumerable
      Dim instanceOfC As Integer() = { 1, 2, 3, 4 }
      If t.IsAssignableFrom(c) Then
         instanceOfT = instanceOfC
      End If  
   End Sub
End Module

因此,此方法可确保如下代码行将在运行时执行,而不会引发 InvalidCastException 异常或类似异常:

instanceOfT = instanceOfC;
instanceOfT <- instanceOfC
instanceOfT = instanceOfC

此方法可由派生类重写。

注意

无法从封闭的构造类型分配泛型类型定义。 也就是说,不能将 Visual Basic) 中的封闭构造类型 MyGenericList<int> (MyGenericList(Of Integer) 分配给 类型的 MyGenericList<T>变量。

c如果参数的类型TypeBuilder为 ,则结果基于要生成的类型。 下面的代码示例使用名为 的 B生成类型对此进行了演示。

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
open System
open System.Reflection
open System.Reflection.Emit

type A() = class end

let domain = AppDomain.CurrentDomain
let assemName = AssemblyName()
assemName.Name <- "TempAssembly"

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

// Define a dynamic module in this assembly.
let moduleBuilder = 
    assemBuilder.DefineDynamicModule "TempModule"

let b1 = moduleBuilder.DefineType("B", TypeAttributes.Public, typeof<A>)
printfn $"{typeof<A>.IsAssignableFrom b1}"
// The example displays the following output:
//        True
Imports System.Reflection
Imports System.Reflection.Emit

Public Class A
End Class

Module Example
   Public Sub Main()
      Dim domain As AppDomain = AppDomain.CurrentDomain
      Dim assemName As New AssemblyName()
      assemName.Name = "TempAssembly"

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

      ' Define a dynamic module in this assembly.
      Dim moduleBuilder As ModuleBuilder = assemBuilder.DefineDynamicModule("TempModule")

      Dim b1 As TypeBuilder = moduleBuilder.DefineType("B", TypeAttributes.Public, GetType(A))
      Console.WriteLine(GetType(A).IsAssignableFrom(b1))
   End Sub
End Module
' The example displays the following output:
'       True

适用于