[Answered] Class Reference Types question lazarus / 62-General ---------------------------------------------------------------------- devEric69 · 2021-11-04 14:28 Hello, I have a class that has the same oveloaded method, like this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type...\...    procedure DoIt(o_ctrl: TLabel); overloaded;    procedure DoIt(o_ctrl: TEdit); overloaded;    procedure DoIt(o_ctrl: TMemo); overloaded;...\... I'm trying to make a kind of polymorphic call to the right method using a class reference, with minimalist source coding, like this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type    TVisualControlRefClass = Class of TControl;  ...\... var    aTypeOfVisualControl: TVisualControlRefClass; ...\... begin    aTypeOfVisualControl:= o_ctrl.ClassType; // ✗ it dosn't compile    Self.DoIt( aTypeOfVisualControl(o_ctrl) );end; I had understood that class reference types were created to do this kind of completely polymorphic code at run-time, i.e. to store a type (retrieved via ClassType) in a variable. I missed something? ---------------------------------------------------------------------- SymbolicFrank · 2021-11-04 14:43 Unless I don't understand, this is what generics are for. ---------------------------------------------------------------------- devEric69 · 2021-11-04 15:06 This is also what I think . The class references - alone - have not been pushed to their logical limits, amo. It's a concept I'm going to forget about, because that confuses me more than anything else, and it never leads to anything really useful, as far as I'm concerned . If I'm turning myself towards generics, to do the same thing (I need to store miscellaneous control Types), does this kind of specialization could work \  be the most appropriate? Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type  TfpSpeGMapOfVisualCtrlRefClass= specialize TfpGMapObject ; ---------------------------------------------------------------------- devEric69 · 2021-11-04 15:39 For information, the above declaration doesn't compile. The compiler notifies me that: Error: Only class methods, class properties and class variables can be referred with class references (edit after @ASerge post: I've got the explanation of the message here: a Class Ref isn't a Class: that's all). I've found a similar post ( https://forum.lazarus.freepascal.org/index .php/topic,50209.msg366155.html#msg366155 ) ==> I need to study generics more (to be able to efficiently store a Type as a variable, whatever the used storage structure)... ---------------------------------------------------------------------- ASerge · 2021-11-04 16:33 Quote from: devEric69 on November 04, 2021, 03:28:47 pmCode: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type...\...    procedure DoIt(o_ctrl: TLabel); overloaded;    procedure DoIt(o_ctrl: TEdit); overloaded;    procedure DoIt(o_ctrl: TMemo); overloaded;...\...I'm trying to make a kind of polymorphic call to the right method using a class reference For overloading used overload keyword, not overloaded. Overloading and generic is static polymorphism - only at compile time. Class references used for dynamic polymorphism, for example to create different types of objects, that are unknown at compile time. For code implementing a dynamic polymorphic function, you need to use either an explicit iteration of the class name (via case of) or a hidden one (via DispatchStr). Example: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   case C.ClassName of    'TLabel': DoIt(TLabel(C));    'TEdit': DoIt(TEdit(C));    'TMemo': DoIt(TMemo(C));  else    // Some code for unsupported controls  end; ---------------------------------------------------------------------- devEric69 · 2021-11-04 17:22 Quote from: ASerge on November 04, 2021, 05:33:43 pmFor code implementing a dynamic polymorphic function, you need to use either an explicit iteration of the class name (via case of) or a hidden one (via DispatchStr). Thank you very much for the iterated example, and the idea. Quote from: ASerge on November 04, 2021, 05:33:43 pmClass references used for dynamic polymorphism, for example to create different types of objects, that are unknown at compile time. Yes: this is THE applied example (BUT the only one, apparently) that I can found on the internet. Hence my question: really, "Class references" - or another concept - can't be used as variable to store a true type (TLabel, TEdit, ...), in order to be used to transtype an object pointer (I'm just extrapolating this endless and alone dynamic polymorphism creation example found on internet)? ---------------------------------------------------------------------- devEric69 · 2021-11-04 18:10 Well, using this post, I'm able to store true types (TLabel, TEdit, ...) inside a variable (with specialize TFPGMap;): it's great. But the call to DoIt( o_ctrl as FofpSpeControlClassRef.KeyData[Sender.ClassName] ); refuses to compile such a type-casting \ transtyping ==> I'll use the iterated method. Thanks. ---------------------------------------------------------------------- Thaddy · 2021-11-04 20:54 More in general, one would use the factory pattern, i.e. a factory from the reference declared. ---------------------------------------------------------------------- devEric69 · 2021-11-05 09:17 OK, I think I understand: if I'm in a serialized (according to the type it applies to) source code, but I can't transtype it with a class reference (what bothered me), then I reverse the logic creating a hierarchy objects - one TClass\type by each impossible transtyping - i.e. something like this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type TobjToDoItOnTControl =  class;     {with its DoIt(o_ctrl: Tcontrol); abstract; virtual;}   TobjToDoItOnTLabel =  class(TobjToDoItOnTControl);     procedure DoIt(o_ctrl: TControl); override;     begin       with TLabel(o_ctrl) do begin      ...\...    end;    end;  TobjToDoItOnTEdit =  class(TobjToDoItOnTControl);    procedure DoIt(o_ctrl: TControl); override;    begin       with TEdit(o_ctrl) do begin      ...\...      end;    end; Then, I create a class reference which can store only the types of this hierarchy. I create a fabrication of this hierarchy, which according to the "creational" token (o_ctrl: TControl), will choose how to affect correctly the ref.-class variable (among the types of my hierarchy) with a type, and will perform the appropriate polymorphism call to Create (  aToDoItOnTCtrlRef.Create(o_ctrl: Tcontrol);  ) inside de fabrication: so, a kind of "2 stroke transtyping". This solution also suits me. Thank you. ---------------------------------------------------------------------- Thaddy · 2021-11-05 09:28 Yes. That is what I mean. (combined with the other answers) ---------------------------------------------------------------------- PascalDragon · 2021-11-05 12:19 Quote from: devEric69 on November 04, 2021, 03:28:47 pmHello, I have a class that has the same oveloaded method, like this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type...\...    procedure DoIt(o_ctrl: TLabel); overloaded;    procedure DoIt(o_ctrl: TEdit); overloaded;    procedure DoIt(o_ctrl: TMemo); overloaded;...\... I'm trying to make a kind of polymorphic call to the right method using a class reference, with minimalist source coding, like this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type    TVisualControlRefClass = Class of TControl;  ...\... var    aTypeOfVisualControl: TVisualControlRefClass; ...\... begin    aTypeOfVisualControl:= o_ctrl.ClassType; // ✗ it dosn't compile    Self.DoIt( aTypeOfVisualControl(o_ctrl) );end; I had understood that class reference types were created to do this kind of completely polymorphic code at run-time, i.e. to store a type (retrieved via ClassType) in a variable. I missed something? The compiler needs to know at compile time which method signature is to be used, that's why you can't call DoIt like that. Quote from: devEric69 on November 04, 2021, 07:10:48 pmBut the call to DoIt( o_ctrl as FofpSpeControlClassRef.KeyData[Sender.ClassName] ); refuses to compile such a type-casting \ transtyping ==> I'll use the iterated method. Same as above: the right side of the as-operator must be known at compile time, cause the result type of the expression will be the type of the right side. ---------------------------------------------------------------------- devEric69 · 2021-11-05 13:06 Yes, understood. In fact, I had hoped that if FofpSpeControlClassRef was filled with the same types (content of the list actually known exhaustively only at run-time; now, it's clear ==> so I needed to beat and drop the list of the " apple Types " from the tree for the compile-time, in some way or another: an implemented hierarchy or specialised types via a common orthogonality, using a class reference variable to bind them together) as those in the enumeration of the overloaded methods (through the overloading said parameters types), the compiler would have - perhaps - let the compilation pass... That being said, I have no compiler skills. And the compiler is always right. ---------------------------------------------------------------------- SymbolicFrank · 2021-11-05 17:13 Well, it might be possible with Run-Time Type Information, but I don't know how much info that has at the moment. A few years ago it wasn't possible, but Thaddy said they were working on it.