Рефлексия. Рефлексия пользовательских типов. Клиентское приложение, страница 2

Для проверки функционирования введите: System.DateTime, System.Decimal, System.Array. Вывод будет таким:

Created: System.DateTime, Default value: 01.01.0001 0:00:00

Created: System.Decimal, Default value: 0

Cannot create an abstract class.

Теперь покажем, как создать объекты своих типов. Вставьте внутрь класса Test определения двух новых типов.

public class Man

{

private string name;

private int age;

public Man() { name = "N/A"; age = 0; }

public override string ToString()

{

return name.PadRight(10) + "; Age: " + age;

}

}

public enum Military { Soldier, Captain, Colonel, General };

Затем запустите приложение и введите: Test+Man или Test+Military.

Created: Test+Man, Default value: N/A       ; Age: 0

Created: Test+Military, Default value: Soldier

Рассмотрим рефлексию массива данных типа decimal.

decimal[] money = { 1.25m, 1000, -12000m };

Type type = money.GetType();

Console.WriteLine("{0,20}  is located in :  {1}", type.Name, type.Module);

Console.WriteLine("{0,20}  is Value Type?:  {1}", type.Name, type.IsValueType);

Console.WriteLine("{0,20}  is Object ?   :  {1}", type.Name,

type.IsSubclassOf(typeof(object)));

Console.WriteLine("{0,20}  is Array ?    :  {1}", type.Name, type.IsArray);

Console.WriteLine("{0,20}  is Pointer ?  :  {1}", type.Name, type.IsPointer);

Console.WriteLine("{0,20}  is a Generic ?:  {1}", type.Name, type.IsGenericType);

Мы получим такой вывод:

Decimal[]  is located in :  CommonLanguageRuntimeLibrary

Decimal[]  is Value Type?:  False

Decimal[]  is Object ?   :  True

Decimal[]  is Array ?    :  True

Decimal[]  is Pointer ?  :  False

Decimal[]  is a Generic ?:  False

Что же такое Generic Type? Это шаблоны будущих классов. Реальный класс будет сгенерирован автоматически в тот момент, когда станет известен тип параметров его шаблона.

Добавим внутрь класса Test объявление встроенных классов (Generic-типов).

public class People<T, U> { }

public class Things<T> { }

public class BadPeople<V> : People<string, int>

{

public Things<BadPeople<string>> things;

public class Car { }

}

Теперь в методе Main класса Test мы можем поиграть с Generic-типами.

Type type = typeof(People<,>);

Console.WriteLine("{0,20}  is Generic ?  :  {1}", type.Name, type.IsGenericType);

Console.WriteLine("{0,20}  is Nested ?   :  {1}", type.Name, type.IsNested);

Type t = type.GetGenericArguments()[0];

Console.WriteLine("{0,20}  is Object  ?  :  {1}", t.Name, t.IsSubclassOf(typeof(object)));

t = type.GetGenericArguments()[1];

Console.WriteLine("{0,20}  is Object  ?  :  {1}", t.Name, t.IsSubclassOf(typeof(object)));

type = typeof(BadPeople<>);

Console.WriteLine("{0,20}  is Generic ?  :  {1}", type.Name, type.IsGenericType);

Console.WriteLine("{0,20}  are People ?  :  {1}", type.Name,

type.IsSubclassOf(typeof(People<string,int>)));

Console.WriteLine("{0,20}  are objects of People ?   :  {1}", type.Name,

type.IsInstanceOfType(typeof(People<,>)));

t = type.GetField("things").FieldType;

Console.WriteLine("{0,20}  is Generic ?   :  {1}", t.Name, t.IsGenericType);

Console.WriteLine("{0,20}  is Nested  ?   :  {1}", t.Name, t.IsNested);

Console.WriteLine("{0,20}  is GenericTypeDefinition ?   :  {1}", t.Name,

t.IsGenericTypeDefinition);

Console.WriteLine("{0,20}  ContainsGenericParameters ? :  {1}", t.Name,

t.ContainsGenericParameters);

type = typeof(BadPeople<>.Car);

Console.WriteLine("{0,20}  is GenericTypeDefinition ?   :  {1}", type.Name,

type.IsGenericTypeDefinition);

Console.WriteLine("{0,20}  ContainsGenericParameters ? :  {1}", type.Name,

type.ContainsGenericParameters);

Наш код произведет такой вывод:

People`2  is Generic ?  :  True

People`2  is Nested ?   :  True

T  is Object  ?  :  True

U  is Object  ?  :  True

BadPeople`1  is Generic ?  :  True

BadPeople`1  are People ?  :  True

BadPeople`1  are objects of People ?   :  False

Things`1  is Generic ?   :  True

Things`1  is Nested  ?   :  True

Things`1  is GenericTypeDefinition ?   :  False

Things`1  ContainsGenericParameters ? :  False

Car  is GenericTypeDefinition ?   :  True

Car  ContainsGenericParameters ? :  True

Мы рассмотрели механизм позднего связывания с типами данных. Теперь покажем, как с помощью классов из пространства имен System.Reflection.Emit можно на лету создать .NET MSIL-код и на лету заставить его работать.

Генерация кода