RayTmsk 0 Posted April 26 Hi all! I need to set object from several types of arrays: procedure SetAsGuidArray(SourceItems: TArray<TGuid>); procedure SetAsIntArray(SourceItems: TArray<integer>); procedure SetAsStringArray(SourceItems: TArray<string>); and so on... What is modern way for do this without many code? procedure SetAsAnyArray(SourceItems: TArray<??>); will be good but impossible... may be interesting way exist for such constructions ? Share this post Link to post
Dmitry Arefiev 101 Posted April 26 Please show the code for one "procedure SetAsGuidArray(SourceItems: TArray<TGuid>); " as an example Share this post Link to post
RayTmsk 0 Posted April 27 procedure TDataField.SetAsGuidArray(SourceItems: TArray<TGuid>); begin DataType := ftArray; FArrayItemType := ftGuid; FDataArrayGuids := SourceItems; end; Share this post Link to post
David Heffernan 2345 Posted April 27 2 hours ago, RayTmsk said: procedure TDataField.SetAsGuidArray(SourceItems: TArray<TGuid>); begin DataType := ftArray; FArrayItemType := ftGuid; FDataArrayGuids := SourceItems; end; Are you sure this is right? It takes a reference to the array rather than a copy. Share this post Link to post
RayTmsk 0 Posted April 27 6 hours ago, David Heffernan said: Are you sure this is right? It takes a reference to the array rather than a copy. Not tested now but... I'd like to think it works the same way as the strings. Reference at first assign and hard copy while changing. Share this post Link to post
Uwe Raabe 2057 Posted April 27 37 minutes ago, RayTmsk said: Reference at first assign and hard copy while changing. That is true for strings, but nor for dynamic arrays. 2 Share this post Link to post
Remy Lebeau 1394 Posted April 27 (edited) On 4/26/2024 at 7:49 AM, RayTmsk said: What is modern way for do this without many code? You can use a Generic so you have only 1 method to declare and implement which can accept multiple types as input, eg: procedure TDataField.SetAsAnyArray<T>(SourceItems: TArray<T>); But, it looks like you have different data members for each array type, so you would have to use RTTI to detect the actual type used for T and write different code branches to handle each type that you want T to accept. That's not much better than just writing a separate method for each type of T. Edited April 27 by Remy Lebeau Share this post Link to post
RayTmsk 0 Posted April 27 15 minutes ago, Uwe Raabe said: That is true for strings, but nor for dynamic arrays. Yes, you are right. But.. What about topic question? Share this post Link to post
RayTmsk 0 Posted April 27 16 minutes ago, Remy Lebeau said: But, it looks like you have different data members for each array type, so you would have to use RTTI to detect the actual type used for T and write different code branches to handle each type that you want T to accept. That's not much better than just writing a separate method for each type of T. Hmm... but how to detect real type of T ? in first iterations I need for int, guid, string, float. Any reference to vcl source or article, please... 🙂 Share this post Link to post
David Heffernan 2345 Posted April 27 18 minutes ago, RayTmsk said: What about topic question? Well, knowing what you are doing in the setter functions is likely important to decide how to write them. You want to take copies? And do you have one member field for each array type? Anyway, I'm also of the opinion that a branching generic method is little better than a series of overloads. Share this post Link to post
RayTmsk 0 Posted April 27 5 minutes ago, David Heffernan said: Well, knowing what you are doing in the setter functions is likely important to decide how to write them. You want to take copies? And do you have one member field for each array type? Yes, I want to do copies. As stupid decision planning to create several internal array for hold data: FDataArrayGuids, FDataArrayStrings, FDataArrayIntegers... I find good method as sample unit System.Generics.Collections; class function TArray.ToString<T> Share this post Link to post
Remy Lebeau 1394 Posted April 27 4 hours ago, RayTmsk said: Hmm... but how to detect real type of T ? in first iterations I need for int, guid, string, float. For example: procedure TDataField.SetAsAnyArray<T>(SourceItems: TArray<T>); begin case GetTypeKind(T) of tkInteger: begin ... end; tkUString: begin ... end; tkFloat: begin ... end; tkRecord: begin if TypeInfo(T) <> TypeInfo(TGuid) then raise ...; ... end; else raise ...; end; end; Share this post Link to post