unit Program1;
interface
type
t1=class;
t2=class;
t1=class
a:t2;
procedure p1;
end;
t2=class
a:t1;
procedure p1;
end;
implementation
procedure t1.p1 := writeln(self.a.a);
procedure t2.p1 := writeln(self.a.a);
end.
Спасибо, но Вы меня не поняли. Нужна примерно такая структура:
Type
B = class
procedure MB();
Begin
//Тут нужно использовать текущие значение a1 и a2.
//Эти классы могут быть расположены в разных модулях
End;
end;
A = class
a1,a2: integer;
procedure MA();
Begin
Var B1 := new B; //Тут в конструктор B можно передать a1 и a2,
//но при их изменении в объекте класса A они не изменятся в B1
End;
End;
Begin
End.
unit Program1;
interface
type
A=class;
B=class;
A=class
a1,a2:integer;
procedure MA;
end;
B=class
procedure MB;
end;
implementation
procedure A.MA;
begin
Var B1 := new B; //Тут в конструктор B можно передать a1 и a2,
//но при их изменении в объекте класса A они не изменятся в B1
end;
procedure B.MB;
begin
//Тут нужно использовать текущие значение a1 и a2.
//Эти классы могут быть расположены в разных модулях
end;
end.
В этой программе оба метода относятся к классу A. Тогда должно быть
procedure B.MB;
begin
//Тут нужно использовать текущие значение a1 и a2.
//Эти классы могут быть расположены в разных модулях
end;
но из этого метода нельзя обратиться к a1,a2
Ой действительно, опечатался, уже исправил.
a1
и a2
это поля класса A
.
Так будет работать:
procedure B.MB;
begin
var varA := new A;
varA.a1 := 5;
end;
Будет, но мою задаю это не решает=)) Надо ведь наоборот: в методе A.MA
создать экземпляр класса B и в методе B.MB использовать переменные a1,a2 того объекта, в котором этот экземпляр создаётся. Наверно, здесь это невозможно… в C# есть вложенные классы, в ABC.NET можно создать нечто подобное через анонимные классы. Но это гораздо более громоздко, и не позволяет использовать все возможности вложенных классов.
Ну можно a1
и a2
передать в виде параметров конструктора или процедуры, а вообще я не совсем понял задание)) Давайте хотя бы на C# код.
Да на C#-то это легко реализуется: https://docs.microsoft.com/ru-ru/dotnet/csharp/programming-guide/classes-and-structs/nested-types а здесь так нельзя… Эх, кажется я плохо понимаю, что делаю. Вопрос закрыт.
Чтобы получить доступ к вмещающему типу, передайте его в качестве аргумента в конструктор вложенного типа. (это я со страницы с вашей ссылки скопировал)
Как я и сказал, передавайте данные через конструктор.
Напишите плиз какой-нибудь простой пример использования метода ForeEach, с применением действия зависящего от индекса элемента. Например нужно каждый элемент последовательности перевести в степень его же индекса. ForeEach подойдет для этого?
Пример для ForEach имеется в стандартной поставке:
\PABCWork.NET\Samples\!MainFeatures\01_First\Foreach.pas
Что касается примера “ForEach с применением индекса” - Вы сами хорошо осознаете, что просите? Метод ForEach, как и цикл ForEach используется для перебора всех элементов БЕЗ обращения к их индексу, даже если таковой имеется. Откуда же в ForEach (и зачем) этот индекс возьмется?
Есть 2 Foreach
:
-
цикл
Foreach var a in arr do
, он работает не для массивов а для последовательностей. Массив тоже последовательность, но не у все последовательности индексированы, поэтому он не работает с индексами. -
функция
sequence.Foreach
, вторая её перезагрузка производит свою индексацию, поэтому можно сделать так:
begin
var a := new byte[3](5,7,8);
a.ForEach((el,ind)->begin a[ind] *= ind end);
a.Println;
end.
0 7 16
Но это как то через 5 точку, лучше так:
begin
var a := new byte[3](5,7,8);
a := a.Select((el,ind)->byte(el*ind)).ToArray;
a.Println;
end.
Теперь хотя бы нет обращения из лямбды к внешней переменной, хотя конечно обычный цикл for
всё равно будет быстрее, используйте такой метод только если производительность не важна.
Нужен пример вот этого: “procedure ForEach(Self: sequence of T; action: (T,integer) -> ()); extensionmethod; Применяет действие к каждому элементу последовательности, зависящее от номера элемента”
Благодарю.
С недавних пор есть еще один вариант – через цикл foreach
и метод расширения .Indexes
для одномерных массивов:
begin
var a := new byte[3](5,7,8);
foreach var i in a.Indexes do a[i]*=i;
a.Println;
end.
Красиво, но, к сожалению, работает тоже немного медленнее классического цикла for
…
Можно пример с операторами + и * для функций? Как это вообще работает?
Для функций это не работает. Работает только для процедур без параметров:
var p3 := p1 + p2;
Тут p3
присваивается процедура которая выполняет p1
и затем p2
.
var p2 := p1*5;
А тут p2
присваивается процедура которая выполняет p1
5 раз.
Для функций нет
Извините, ошибся. А будет?
Ну operator+
почему то расширять не даёт, а вот operator*
можно так самому:
function operator*(a: byte->byte; c: integer): byte->byte; extensionmethod;
begin
Result := b -> begin
loop c do Result += a(b);
end;
end;
begin end.
(сейчас не компилируется благодаря #533)