C# – Type.IsAssignableFrom.
Topic: C# –
Type.IsAssignableFrom
标题: C# – Type.IsAssignableFrom 方法
本文讨论的是Type.IsAssignableFrom 方法。
This post
wil introduce you to the Type.IsAssignableFrom method.
Type.IsAssignableFrom方法可以在类型, 类型参数,甚至是在TypeBuilder上应用,如下,该方法应用在TypeBuilder上。
The
Type.IsAssignableFrom method can works on the type, type parameter, or even the
TypeBuilder one, such is shown in the following code.
-
TypeBuilder b1 = moduleBuilder.DefineType("B", TypeAttributes.Public, typeof(A));
-
// Returns true:
-
typeof(A).IsAssignableFrom(b1))
关于IsAssignableFrom方法的返回值:
As a note on the return value of the IsAssignableFrom
method.
true if c and the current Type
represent the same type, or if the current Type is in the inheritance hierarchy
of c, or if the current Type is an interface that c implements, or if c is a
generic type parameter and the current Type represents one of the constraints
of c, or if c represents a value type and the current Type represents
Nullable (Nullable(Of c) in Visual Basic). false if none of these
conditions are true, or if c is null.
为了显示IsAssignableFrom如何工作的,讨论了如下分类的类型
To show how the IsAssignableFrom works, types in the
following categories are compared.
·
类家族,有继承关系的一组类, 比如
Kitchen, Bedroom, MasterBedroom, and Room classes.
·
数组,多维数组
·
泛型和Nullabel<>
·
TypeBuilder 和Dynamic 类型
·
没有继承关系的基本类型
·
自定义类型的类型参数
·
Types from a class hierarchy, like the Kitchen,
Bedroom, MasterBedroom, and Room classes.
·
Arrays, multiple dimension array
·
Generics and Nullable
·
TypeBuilder and Dynamic Types
·
Primitives without inheritance relationship
·
Custom Generic’s Type parameter
This is the main code.
-
class Program
-
{
-
static void Main(string[] args)
-
{
-
TestIsAssignableFrom();
-
}
-
-
static void TestIsAssignableFrom()
-
{
-
-
// 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("room assignable from masterbedroom: {0}", kitchen1Type.IsAssignableFrom(masterbedroom1Type));
-
-
// Demonstrate arrays:
-
Console.WriteLine();
-
Console.WriteLine();
-
-
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] is assignable from int[10]: {0}", array2Type.IsAssignableFrom(array10Type));
-
Console.WriteLine("int[2] is assignable from int[2,4]: {0}", array2Type.IsAssignableFrom(array24Type));
-
Console.WriteLine("int[2,4] is assignable from int[2,2]: {0}", array24Type.IsAssignableFrom(array22Type));
-
-
-
// Demonstrate generics:
-
Console.WriteLine();
-
Console.WriteLine("Generics:");
-
-
// Note that "int?[]" is the same as the "Nullable[]"
-
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 assignable from List: {0}", genIntListType.IsAssignableFrom(genTListType));
-
Console.WriteLine("List assignable from List: {0}", genTListType.IsAssignableFrom(genIntListType));
-
-
// TypeBuilder
-
// Demonstrate TypeBuilder
-
Console.WriteLine();
-
Console.WriteLine("TypeBuilder");
-
-
var bBuilder = new BClassTypeBuilder();
-
TypeBuilder b1 = bBuilder.GetTypeBuilder();
-
Console.WriteLine("typeof(A) assignable from B: {0}", typeof(A).IsAssignableFrom(b1));
-
-
Type bType = bBuilder.CompileResultType();
-
Console.WriteLine("typeof(A) assignable from dynamic type : {0}", typeof(A).IsAssignableFrom(bType));
-
-
// Primitive
-
// demonstrate Primitives
-
Console.WriteLine();
-
Console.WriteLine("Primitives");
-
-
double a = 0.0;
-
float b = 0.0f;
-
Type doubleAType = typeof(double);
-
Type floatBType = typeof(float);
-
-
Console.WriteLine("Typeof(float) assignable from Typeof(double): {0}", floatBType.IsAssignableFrom(doubleAType)); // there is no inheritance relationship between Float and Double type.
-
Console.WriteLine("Typeof(double) assignable from Typeof(float): {0}", floatBType.IsAssignableFrom(doubleAType));
-
-
// Another Custom Generic Test
-
// demonstrate Generics
-
Console.WriteLine();
-
Console.WriteLine("Custom Generics");
-
-
Console.WriteLine("Can make GenericType with TypeBuilder's class: {0}", GenericType<A>.CanMakeGenericType(bType));
-
-
Console.ReadLine();
-
}
-
-
-
class Room
-
{
-
}
-
-
class Kitchen : Room
-
{
-
}
-
-
class Bedroom : Room
-
{
-
}
-
-
class Guestroom : Bedroom
-
{
-
}
-
-
class MasterBedroom : Bedroom
-
{
-
}
-
-
-
public class BClassTypeBuilder
-
{
-
// Build a type that is inheritable from the A class
-
public TypeBuilder GetTypeBuilder()
-
{
-
var typeSignature = "MyDynamicType";
-
AssemblyName an = new AssemblyName(typeSignature);
-
AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run); // Create a Dynamic Assembly, which can be run, but not saved
-
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule");
-
//TypeBuilder tb = moduleBuilder.DefineType(typeSignature,
-
// TypeAttributes.Public |
-
// TypeAttributes.Class |
-
// TypeAttributes.AutoClass |
-
// TypeAttributes.AnsiClass |
-
// TypeAttributes.BeforeFieldInit |
-
// TypeAttributes.AutoLayout,
-
// typeof(A)); // which makes the Type to be built to be a subclass to class A
-
TypeBuilder tb = moduleBuilder.DefineType(typeSignature,
-
TypeAttributes.Public,
-
typeof(A));
-
-
return tb;
-
-
-
//TypeBuilder tb = new TypeBuilder
-
}
-
-
public Type CompileResultType()
-
{
-
TypeBuilder tb = GetTypeBuilder();
-
ConstructorBuilder constructor = tb.DefineDefaultConstructor(
-
MethodAttributes.Public |
-
MethodAttributes.SpecialName |
-
MethodAttributes.RTSpecialName
-
);
-
-
Type objectType = tb.CreateType();
-
return objectType;
-
}
-
}
-
}
-
// Type A cannot be a nested type??
-
//oherwise, you will get TypeLoadException: Cannot load "IsAssignableTest.Program+A"
-
// the accessibility should be "Public"
-
// unless you set TypeB's signature to non-public
-
public class A
-
{ }
-
-
public class GenericType
-
{
-
}
-
-
public class GenericType<T> : GenericType
-
where T : A
-
{
-
public bool CheckType(Type type)
-
{
-
if (type != null)
-
{
-
return type.IsAssignableFrom(typeof(T));
-
}
-
return false;
-
}
-
public static GenericType MakeGenericTypeInstance(Type t)
-
{
-
if (typeof(A).IsAssignableFrom(t))
-
{
-
Type genericOfTType = typeof(GenericType<>).MakeGenericType(t);
-
return (GenericType)Activator.CreateInstance(genericOfTType);
-
}
-
return null;
-
}
-
-
public static GenericType<T> MakeGenericTypeInstance()
-
{
-
return new GenericType<T>();
-
}
-
-
public static Type MakeGenericType()
-
{
-
return typeof(GenericType<T>);
-
}
-
-
public static Type MakeGenericType(Type t)
-
{
-
if (CanMakeGenericType(t))
-
{
-
Type genericOfTType = typeof(GenericType<>).MakeGenericType(t);
-
return genericOfTType;
-
}
-
return null;
-
}
-
-
public static bool CanMakeGenericType(Type t)
-
{
-
return typeof(A).IsAssignableFrom(t);
-
}
-
}
在上面的代码中我们创建了一个TypeBuilder,用这个TypeBuilder,我们创建了dynamic
类,并且在MyGenericType,我们给出了类型约束,我们测试了这个类型约束-它满足Type.IsAssignableFrom,这是说它对于满足类型约束的类型返回的是true.
Like the above, we created a TypeBuilder, with the Type
Builder, we defined a dynamic type, and in the MyGenericType, we have
specified the type constraint, and we tested the type constraint – which
satisfy the Type.IsAssignableFrom, that it returns true for the type
constraint.
References
阅读(2961) | 评论(0) | 转发(0) |