Разработка компиляторов

       

Пример на рефлексию


// Пример, демонстрирующий использование рефлексии // Автор: Антон Москаль, // Санкт-Петербургский государственный университет, 2001

using System; using System.Text; using System.Reflection;

class Sample {

public struct Struct { public String name; public int[] vec; } public static void Main (String[] args) { Struct s; s.name = "Name"; s.vec = new int [2]; s.vec [0] = 1; s.vec [1] = 4; Console.WriteLine (Refl.Repr(s)); } }

На данном слайде приведена программа, вызывающая упомянутую выше функцию распечатки объекта. Результатом работы данного примера будет следующая строка:

STRUCT{name:Name, vec:[2]{1, 4}}

Рассмотрим реализацию функции класса Refl :

class Refl { public static string Repr (Object o) { // получаем дескриптор типа o Type t = o.GetType ();

// если o - массив: if (t.IsArray) return ReprArray ((Array) o); // если o - структура (value type, не являющийся встроенным типом): else if (t.IsValueType && !t.IsPrimitive) return ReprStruct (t, o); // в противном случае используем стандартную фукнцию ToString: else return o.ToString (); }

public static string ReprArray (Array a) { string res = "["+a.Length+"]{"; // и дальше в цикле добавляем в res // список представлений его элементов: String sep = ""; for (int i = 0; i != a.Length; ++i, sep = ", ") // для бестипового массива индексацию почему-то использовать // нельзя, поэтому приходится пользоваться функцией GetValue: res += sep + Repr (a.GetValue (i));

return res + "}"; }

public static string ReprStruct (Type t, Object o) { // получаем массив дескрипторов полей: FieldInfo [] flds = t.GetFields (); string res = "STRUCT{"; String sep = ""; // в цикле добавляем представления полей в виде // <имя поля>: <значение поля> foreach (FieldInfo fld in flds) { // метод GetValue в дескриторе поля // позволяет выбрать это поле из объекта: res += sep + fld.Name + ":" + Repr (fld.GetValue (o)); sep = ", "; } return res + "}"; } }



Содержание раздела