Chinaunix首页 | 论坛 | 博客
  • 博客访问: 49394
  • 博文数量: 21
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 190
  • 用 户 组: 普通用户
  • 注册时间: 2010-11-24 15:25
文章分类

全部博文(21)

文章存档

2013年(21)

我的朋友

分类: C#/.net

2013-07-05 18:07:13

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.

点击(此处)折叠或打开

  1. TypeBuilder b1 = moduleBuilder.DefineType("B", TypeAttributes.Public, typeof(A));
  2. // Returns true:
  3. 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.

点击(此处)折叠或打开

  1. class Program
  2.     {
  3.         static void Main(string[] args)
  4.         {
  5.             TestIsAssignableFrom();
  6.         }
  7.  
  8.         static void TestIsAssignableFrom()
  9.         {
  10.  
  11.             // Demonstrate classes
  12.             Console.WriteLine("Defined Classes:");
  13.             Room room1 = new Room();
  14.             Kitchen kitchen1 = new Kitchen();
  15.             Bedroom bedroom1 = new Bedroom();
  16.             Guestroom guestroom1 = new Guestroom();
  17.             MasterBedroom masterbedroom1 = new MasterBedroom();
  18.  
  19.             Type room1Type = room1.GetType();
  20.             Type kitchen1Type = kitchen1.GetType();
  21.             Type bedroom1Type = bedroom1.GetType();
  22.             Type guestroom1Type = guestroom1.GetType();
  23.             Type masterbedroom1Type = masterbedroom1.GetType();
  24.  
  25.             Console.WriteLine("room assignable from kitchen: {0}", room1Type.IsAssignableFrom(kitchen1Type));
  26.             Console.WriteLine("bedroom assignable from guestroom: {0}", bedroom1Type.IsAssignableFrom(guestroom1Type));
  27.             Console.WriteLine("room assignable from masterbedroom: {0}", kitchen1Type.IsAssignableFrom(masterbedroom1Type));
  28.  
  29.             // Demonstrate arrays:
  30.             Console.WriteLine();
  31.             Console.WriteLine();
  32.  
  33.             int[] array2 = new int[2];
  34.             int[] array10 = new int[10];
  35.             int[,] array22 = new int[2, 2];
  36.             int[,] array24 = new int[2, 4];
  37.  
  38.             Type array2Type = array2.GetType();
  39.             Type array10Type = array10.GetType();
  40.             Type array22Type = array22.GetType();
  41.             Type array24Type = array24.GetType();
  42.  
  43.             Console.WriteLine("int[2] is assignable from int[10]: {0}", array2Type.IsAssignableFrom(array10Type));
  44.             Console.WriteLine("int[2] is assignable from int[2,4]: {0}", array2Type.IsAssignableFrom(array24Type));
  45.             Console.WriteLine("int[2,4] is assignable from int[2,2]: {0}", array24Type.IsAssignableFrom(array22Type));
  46.  
  47.  
  48.             // Demonstrate generics:
  49.             Console.WriteLine();
  50.             Console.WriteLine("Generics:");
  51.  
  52.             // Note that "int?[]" is the same as the "Nullable[]"
  53.             int?[] arrayNull = new int?[10];
  54.             List<int> genIntList = new List<int>();
  55.             List<Type> genTList = new List<Type>();
  56.  
  57.             Type arrayNullType = arrayNull.GetType();
  58.             Type genIntListType = genIntList.GetType();
  59.             Type genTListType = genTList.GetType();
  60.  
  61.             Console.WriteLine("int[10] assignable from int?[10]: {0}", array10Type.IsAssignableFrom(arrayNullType));
  62.             Console.WriteLine("List assignable from List: {0}", genIntListType.IsAssignableFrom(genTListType));
  63.             Console.WriteLine("List assignable from List: {0}", genTListType.IsAssignableFrom(genIntListType));
  64.  
  65.             // TypeBuilder
  66.             // Demonstrate TypeBuilder
  67.             Console.WriteLine();
  68.             Console.WriteLine("TypeBuilder");
  69.  
  70.             var bBuilder = new BClassTypeBuilder();
  71.             TypeBuilder b1 = bBuilder.GetTypeBuilder();
  72.             Console.WriteLine("typeof(A) assignable from B: {0}", typeof(A).IsAssignableFrom(b1));
  73.  
  74.             Type bType = bBuilder.CompileResultType();
  75.             Console.WriteLine("typeof(A) assignable from dynamic type : {0}", typeof(A).IsAssignableFrom(bType));
  76.  
  77.             // Primitive
  78.             // demonstrate Primitives
  79.             Console.WriteLine();
  80.             Console.WriteLine("Primitives");
  81.  
  82.             double a = 0.0;
  83.             float b = 0.0f;
  84.             Type doubleAType = typeof(double);
  85.             Type floatBType = typeof(float);
  86.  
  87.             Console.WriteLine("Typeof(float) assignable from Typeof(double): {0}", floatBType.IsAssignableFrom(doubleAType)); // there is no inheritance relationship between Float and Double type.
  88.             Console.WriteLine("Typeof(double) assignable from Typeof(float): {0}", floatBType.IsAssignableFrom(doubleAType));
  89.  
  90.             // Another Custom Generic Test
  91.             // demonstrate Generics
  92.             Console.WriteLine();
  93.             Console.WriteLine("Custom Generics");
  94.  
  95.             Console.WriteLine("Can make GenericType with TypeBuilder's class: {0}", GenericType<A>.CanMakeGenericType(bType));
  96.  
  97.             Console.ReadLine();
  98.         }
  99.  
  100.  
  101.         class Room
  102.         {
  103.         }
  104.  
  105.         class Kitchen : Room
  106.         {
  107.         }
  108.  
  109.         class Bedroom : Room
  110.         {
  111.         }
  112.  
  113.         class Guestroom : Bedroom
  114.         {
  115.         }
  116.  
  117.         class MasterBedroom : Bedroom
  118.         {
  119.         }
  120.  
  121.  
  122.         public class BClassTypeBuilder
  123.         {
  124.             // Build a type that is inheritable from the A class
  125.             public TypeBuilder GetTypeBuilder()
  126.             {
  127.                 var typeSignature = "MyDynamicType";
  128.                 AssemblyName an = new AssemblyName(typeSignature);
  129.                 AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run); // Create a Dynamic Assembly, which can be run, but not saved
  130.                 ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule");
  131.                 //TypeBuilder tb = moduleBuilder.DefineType(typeSignature,
  132.                 // TypeAttributes.Public |
  133.                 // TypeAttributes.Class |
  134.                 // TypeAttributes.AutoClass |
  135.                 // TypeAttributes.AnsiClass |
  136.                 // TypeAttributes.BeforeFieldInit |
  137.                 // TypeAttributes.AutoLayout,
  138.                 // typeof(A)); // which makes the Type to be built to be a subclass to class A
  139.                 TypeBuilder tb = moduleBuilder.DefineType(typeSignature,
  140.                     TypeAttributes.Public,
  141.                     typeof(A));
  142.  
  143.                 return tb;
  144.  
  145.  
  146.                 //TypeBuilder tb = new TypeBuilder
  147.             }
  148.  
  149.             public Type CompileResultType()
  150.             {
  151.                 TypeBuilder tb = GetTypeBuilder();
  152.                 ConstructorBuilder constructor = tb.DefineDefaultConstructor(
  153.                     MethodAttributes.Public |
  154.                     MethodAttributes.SpecialName |
  155.                     MethodAttributes.RTSpecialName
  156.                     );
  157.  
  158.                 Type objectType = tb.CreateType();
  159.                 return objectType;
  160.             }
  161.         }
  162.     }
  163.     // Type A cannot be a nested type??
  164.     //oherwise, you will get TypeLoadException: Cannot load "IsAssignableTest.Program+A"
  165.     // the accessibility should be "Public"
  166.     // unless you set TypeB's signature to non-public
  167.     public class A
  168.     { }
  169.  
  170.     public class GenericType
  171.     {
  172.     }
  173.  
  174.     public class GenericType<T> : GenericType
  175.         where T : A
  176.     {
  177.         public bool CheckType(Type type)
  178.         {
  179.             if (type != null)
  180.             {
  181.                 return type.IsAssignableFrom(typeof(T));
  182.             }
  183.             return false;
  184.         }
  185.         public static GenericType MakeGenericTypeInstance(Type t)
  186.         {
  187.             if (typeof(A).IsAssignableFrom(t))
  188.             {
  189.                 Type genericOfTType = typeof(GenericType<>).MakeGenericType(t);
  190.                 return (GenericType)Activator.CreateInstance(genericOfTType);
  191.             }
  192.             return null;
  193.         }
  194.  
  195.         public static GenericType<T> MakeGenericTypeInstance()
  196.         {
  197.             return new GenericType<T>();
  198.         }
  199.  
  200.         public static Type MakeGenericType()
  201.         {
  202.             return typeof(GenericType<T>);
  203.         }
  204.  
  205.         public static Type MakeGenericType(Type t)
  206.         {
  207.             if (CanMakeGenericType(t))
  208.             {
  209.                 Type genericOfTType = typeof(GenericType<>).MakeGenericType(t);
  210.                 return genericOfTType;
  211.             }
  212.             return null;
  213.         }
  214.  
  215.         public static bool CanMakeGenericType(Type t)
  216.         {
  217.             return typeof(A).IsAssignableFrom(t);
  218.         }
  219.     }

在上面的代码中我们创建了一个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) |
给主人留下些什么吧!~~