Forum > General
Method of Field as getter/setter for property
soerensen3:
I'm trying to simplify declaring properties with my smart pointer class and I remember there was some way you could access a method of a field and use it for a getter or setter of another class containing this field. It might become more clear if you look at this code.
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---program Project1; uses Classes; type generic ITestProp < T: TObject > = interface ['{B0585610-BE1D-449E-A5D7-08E6DA9A3692}'] function GetTestProp: T; procedure SetTestProp(AValue: T); end; { TTestProp } generic TTestProp < T: TObject > = class ( TInterfacedPersistent, specialize ITestProp < T > ) published function GetTestProp: T; procedure SetTestProp(AValue: T); property TestProp: T read GetTestProp write SetTestProp; end; TClass1 = class end; TClass2 = class protected FTestProp: specialize TTestProp < TClass1 >; FITestProp: specialize ITestProp < TClass1 >; public // Both of these property definitions do not work at the moment. property Prop: TClass1 read FTestProp.GetTestProp write FTestProp.SetTestProp; // Declaring the property without an interface property Prop2: TClass1 read FITestProp.GetTestProp write FITestProp.SetTestProp; // Declaring the property with an interface end; { TTestProp } function TTestProp.GetTestProp: T;begin end; procedure TTestProp.SetTestProp(AValue: T);begin end; beginend. With both property declarations I get an error like this: "project1.lpr(59,45) Error: Unknown record field identifier "GetTestProp"" (For all getters and setters). It doesn't help using a record instead of a class for the field. Was this feature removed or do I do anything wrong? I couldn't find it in the docs either.
Martin_fr:
This only works, if the field (FTestProp) is of type record.
soerensen3:
Unfortunately not even then:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---program Project1; {$modeswitch ADVANCEDRECORDS} uses Classes; type { TTestProp } generic TTestProp < T: TObject > = record function GetTestProp: T; procedure SetTestProp(AValue: T); property TestProp: T read GetTestProp write SetTestProp; end; TClass1 = class end; TClass2 = class protected FTestProp: specialize TTestProp < TClass1 >; public property Prop: TClass1 read FTestProp.GetTestProp write FTestProp.SetTestProp; // Declaring the property without an interface end; { TTestProp } function TTestProp.GetTestProp: T;begin end; procedure TTestProp.SetTestProp(AValue: T);begin end; beginend.
soerensen3:
What however works is:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---program Project1; {$modeswitch ADVANCEDRECORDS} uses Classes; type { TTestProp } generic TTestProp < T: TObject > = record FTestProp: T; property TestProp: T read FTestProp write FTestProp; end; TClass1 = class end; TClass2 = class protected FTestProp: specialize TTestProp < TClass1 >; public property Prop: TClass1 read FTestProp.FTestProp write FTestProp.FTestProp; // Declaring the property without an interface end; beginend. But not with methods. I thought I've seen it with methods before (Maybe in combination with interfaces? But I tried that as well, see the original example). I might be wrong though..
Thaddy:
--- Quote from: soerensen3 on July 23, 2018, 12:42:52 pm --- Was this feature removed or do I do anything wrong? I couldn't find it in the docs either.
--- End quote ---
It was never a feature in the first place, at least out of the box.
But there is something like the MakeMethod function from KOL - which I happened to co-write :P :P 8-) - that takes a normal procedure or function with a dummy parameter and makes it into a method.
I will add an example later. Works also for Lazarus. Works also on arm.
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---{$ifdef fpc}{$mode delphi}{$H+}{$endif}uses classes;type TNotifyFunc = function(sender:Tobject):integer of object; function readVar(dummy:pointer;sender:Tobject):integer;forward; function MakeMethod( Data, Code: Pointer ): TMethod;forward; type TMyClass = class private FField:Integer; FEvent:TNotifyFunc; public constructor create; Property Someproperty:TNotifyFunc read Fevent; end; constructor TMyClass.Create; begin inherited create; Fevent := TNotifyFunc(MakeMethod(@self,@Readvar)); FField := 100; end; {* Help function to construct TMethod record. Can be useful to assign regular type procedure/function as event handler for event, defined as object method (do not forget, that in that case it must have first dummy parameter to replace @Self, passed in EAX/RAX to methods of object). } function MakeMethod( Data, Code: Pointer ): TMethod;begin Result.Data := Data; Result.Code := Code;end; function readVar(dummy:pointer;sender:Tobject):integer;begin Result := TMyClass(sender).FField;end; var test:TMyClass;begin test := TMyClass.Create; writeln(Test.Someproperty(test)); test.free;end.
Quite a bit of hackery but possible.
Navigation
[0] Message Index
[#] Next page