Руководство разработчика

Проверка принадлежности иерархии

Кроме сравнения типов на точное соответствие, поддерживается проверка указанного типа на принадлежность иерархии объектных типов и интерфейсов. Проверка позволяет выяснить, что объектный тип являтся родителем или более отдаленным предком другого объектного типа. Для интерфейсов проверка позволяет выяснить, что один интерфейс является базовым по отношению к другому или его базовым интерфейсам. Также возможна проверка объектного типа на поддержку указанного интерфейса (в данном случае интерфейс рассматривается как тип-предок).

Ключевое слово РОДИТЕЛЬ играет роль знака = при точном сравнении типов. Для проверки на отсутствие зависимости "базовый тип - дочерний тип" может использоваться ключевое слово НЕ (аналог <> при точном сравнении типов). В качестве левой и правой части проверки может указываться имя типа или выражение, заключенное в конструкцию ТИП(<выражение>). Результатом проверки является значение логического типа. Поддерживаются следующие варианты синтаксиса:

<имя типа1> РОДИТЕЛЬ <имя типа2>
<имя типа1> НЕ РОДИТЕЛЬ <имя типа2>

ТИП ( <выражение> ) РОДИТЕЛЬ <имя типа>
<имя типа> РОДИТЕЛЬ ТИП ( <выражение> )

ТИП ( <выражение> ) НЕ РОДИТЕЛЬ <имя типа>
<имя типа> НЕ РОДИТЕЛЬ ТИП ( <выражение> )

ТИП ( <выражение1> ) РОДИТЕЛЬ ТИП ( <выражение2> )
ТИП ( <выражение1> ) НЕ РОДИТЕЛЬ ТИП ( <выражение2> ) 

Проверки с указанием имен двух типов и для тех случаев, когда тип выражения известен компилятору, выполняются на этапе компиляции, т.е. в код заносится значение ДА или НЕТ. При этом вычисление выражения не происходит. При таком виде проверки для типов, отличных от объектных типов и интерфейсов генерируется ошибка компиляции.

Если на этапе компиляции одно из выражений имеет неопределенный тип, то проверка осуществляется на этапе выполнения с фактическим типом выражения (выражение вычисляется). Если тип вычисленного выражения не является объектным типом или интерфейсом, то ошибки не возникает, а результатом проверки является НЕТ.

Пример:

ИНТЕРФЕЙС и1 []
ИНТЕРФЕЙС и2 []
ИНТЕРФЕЙС и3(и1) []

ТИП т1[]
ТИП т2(и3)[]
ТИП т3(т1, и2)[]
ТИП т4(т3)[]

ВЫЧИСЛИТЬ
  // проверки во время компиляции
  ОТЛАДКА(и1 РОДИТЕЛЬ и2) // НЕТ
  ОТЛАДКА(и3 РОДИТЕЛЬ и1) // НЕТ
  ОТЛАДКА(и1 РОДИТЕЛЬ и3) // ДА
  
  ОТЛАДКА(и1 РОДИТЕЛЬ т1) // НЕТ
  ОТЛАДКА(и3 РОДИТЕЛЬ т2) // ДА
  ОТЛАДКА(и1 РОДИТЕЛЬ т2) // ДА
  
  ОТЛАДКА(т1 РОДИТЕЛЬ т2) // НЕТ
  ОТЛАДКА(т3 РОДИТЕЛЬ т1) // НЕТ
  ОТЛАДКА(т1 РОДИТЕЛЬ т3) // ДА
  ОТЛАДКА(т1 РОДИТЕЛЬ т4) // ДА
  
  //ОТЛАДКА(т1 РОДИТЕЛЬ СТРОКА) // ошибка компиляции
  //ОТЛАДКА(ЧИСЛО РОДИТЕЛЬ т1)  // ошибка компиляции

  // используем переменные неопределенного типа: проверки во время выполнения
  ПЕРЕМ *: п1, п2, п3, п4
  п1 = т1[]
  п2 = т2[]
  п3 = т3[]
  п4 = т4[]

  ОТЛАДКА(и1 РОДИТЕЛЬ ТИП(п1)) // НЕТ
  ОТЛАДКА(и3 РОДИТЕЛЬ ТИП(п2)) // ДА
  ОТЛАДКА(и1 РОДИТЕЛЬ ТИП(п2)) // ДА
  
  ОТЛАДКА(т1 РОДИТЕЛЬ ТИП(п2)) // НЕТ
  ОТЛАДКА(т3 РОДИТЕЛЬ ТИП(п1)) // НЕТ
  ОТЛАДКА(т1 РОДИТЕЛЬ ТИП(п3)) // ДА
  ОТЛАДКА(т1 РОДИТЕЛЬ ТИП(п4)) // ДА
  
  // типы не объекты и не интерфейсы: ошибок во время выполнения нет
  ПЕРЕМ *: п5, п6
  п5 = "Hello"
  п6 = 42
  
  ОТЛАДКА(т1 РОДИТЕЛЬ ТИП(п5) /*-> СТРОКА*/) // НЕТ
  ОТЛАДКА(ТИП(п6) /*-> ЧИСЛО*/ РОДИТЕЛЬ т1)  // НЕТ
КОНЕЦ

См. также: