function System.Collections.Generic.IEnumerable
begin
var g := Self.GetEnumerator();
if g.MoveNext() then
write(g.Current);
while g.MoveNext() do
write(' ', g.Current);
Result := Self;
end;
В результате все классы, реализующие интерфейс IEnumerable
function System.Collections.Generic.IEnumerable
begin
var g := Self.GetEnumerator();
if g.MoveNext() then
write(g.Current);
while g.MoveNext() do
write(' ', g.Current);
Result := Self;
end;
С помощью методов расширения можно перегружать операции.
Для методов расширения имеется ряд ограничений:
* Методы расширения не могут быть виртуальными.
* Если метод расширения имеет то же имя, что и обычный метод, то предпочте5ние отдаётся обычному методу.
Анонимные классы
Иногда необходимо сгенерировать объект класса на лету, не описывая класс. У такого класса нет имени (он анонимный), но известен набор полей.
Объект анонимного класса создаётся следующим образом:
var p := new class(Name := 'Иванов', Age := 20);
Println(p.Name,p.Age);
У объекта p автоматически генерируются публичные поля Name и Age соответствующих типов.
Два объекта принадлежат к одному анонимному классу если они имеют одинаковый набор полей, и эти поля принадлежат к одинаковым типам. Например:
var p1 := new class(Name := 'Петров', Age := 21);
p1 := p;
Если поля безымянного класса инициализируются переменными, то имена полей можно не писать - они генерируются автоматически и их имена и типы совпадают с именами и типами переменных. Например:
var Name := 'Попова';
var Age := 23;
var p := new class(Name, Age);
Println(p.Name,p.Age);
Поля безымянного класса можно также инициализировать переменной с составным именем, имеющим точечную нотацию. В этом случае в качестве имен полей берутся последние имена в точечной нотации. Например:
var d := new DateTime(2015,5,15);
var p := new class(d.Day, d.Month, d.Year);
Println(p.Day, p.Month, p.Year);
Println(p);
Автоклассы
При описании класса перед словом class можно поставить слово auto. Такие классы называются автоклассами. Для автоклассов автоматически генерируется конструктор с параметрами, инициализирующими все поля класса, а также метод ToString, выводящий значения всех полей класса. Например:
type Person = auto class
name: string;
age: integer;
end;
var p := new Person('Иванов',20); // конструктор автокласса генерируется автоматически
writeln(p); // вызывается сгенерированный автоматически метод ToString
Здесь в отличие от действия writeln по умолчанию выводятся значения не только публичных, а всех полей.
Обработка исключений
Обработка исключений: обзор
Когда во время выполнения программы происходит ошибка, генерируется так называемое
Имеется ряд стандартных типов исключений. Можно также определять пользовательские типы исключений.
Если исключение не обработать, то программа завершится с ошибкой. Для обработки исключений используется оператор try ... except.
Обычно исключения возбуждаются в подпрограммах, поскольку разработчик подпрограммы, как правило, не знает, как обработать ошибочную ситуацию. В месте вызова подпрограммы уже, как правило, известно, каким образом следует обрабатывать исключение. Например, пусть разработана следующая функция:
function mymod(a,b: integer): integer;
begin
Result := a - (a div b) * b;
end;
Если вызвать mymod(1,0), то будет возбуждено исключение System.DivideByZeroException целочисленного деления на 0.
Рассмотрим наивную попытку обработать ошибочную ситуацию внутри функции mymod:
function mymod(a,b: integer): integer;
begin
if b = 0 then
writeln('Функция mymod: деление на 0');
Result := a - (a div b) * b;
end;