Lars Fosdal 1792 Posted March 21, 2023 Consider type Use = record public class function When<T>(const aBool: Boolean; const WhenTrue: T; const WhenFalse: T): T; static; inline; end; { Use } class function Use.When<T>(const aBool: Boolean; const WhenTrue, WhenFalse: T): T; begin if aBool then Result := WhenTrue else Result := WhenFalse end; procedure Test(Cond: Boolean); type TObjectClass = class of TObject; var i: Integer; b: Byte; c: Cardinal; w: Word; s: String; d: Double; o: TObjectClass; begin s := Use.When(Cond,'True', 'False'); s := Use.When(Cond, 1, 2).ToString; i := Use.When<Integer>(Cond, 1, -2); b := Use.When<Byte>(Cond, 1, 2); c := Use.When(Cond, 1, 2); w := Use.When(Cond, 1, 2); d := Use.When(Cond, 3.14, 42.0); o := Use<TObjectClass>.When(Cond, TObject, TStringList); end; This is valid code. But i := Use.When<Integer>(Cond, 1, -2); requires the type to be specified. Also w := Use.When(Cond, 1, 128); stops working - actually for any signed or unsigned type - when the second parameter is changed to 128 or higher. It then complains: Why? I though the left hand type would assist in the type inference and hence the parameter validation? Edit: I just noticed that this only happens for Error Insight - not during compilation. Share this post Link to post
Stefan Glienke 2002 Posted March 21, 2023 5 minutes ago, Lars Fosdal said: This is valid code. Apart from the last line which does not compile because Use is not generic. 6 minutes ago, Lars Fosdal said: I though the left hand type would assist in the type inference and hence the parameter validation? You are thinking wrong - Delphi never infers from the lhs but only from the passed parameter. And there is usually takes the type from the first one if you have multiple with the same generic type - that is why it needs help with the 1, -2 combination. Share this post Link to post
Lars Fosdal 1792 Posted March 21, 2023 The code compiles without a warning - also for that last line, @Stefan Glienke. In fact, even b := Use.When<Byte>(Cond, 1, 300); compiles. That is a bit weird, I think. Edit: Note to self - make sure you compile the project that contains the file you are fiddling with. 1 Share this post Link to post
Stefan Glienke 2002 Posted March 21, 2023 (edited) 9 minutes ago, Lars Fosdal said: The code compiles without a warning It does not - check again your code - it says: o := Use<TObjectClass>.When(Cond, TObject, TStringList); but clearly, you meant: o := Use.When<TObjectClass>(Cond, TObject, TStringList); 9 minutes ago, Lars Fosdal said: In fact, even b := Use.When<Byte>(Cond, 1, 300); compiles. That is a bit weird, I think. No, it does not (in 11.3). And even in older versions, assigning any literal to Byte that is not within 0..255 always gives an E1012 Edited March 21, 2023 by Stefan Glienke Share this post Link to post
Lars Fosdal 1792 Posted March 21, 2023 o := Use<TObjectClass>.When(Cond, TObject, TStringList); I did indeed mean o := Use.When<TObjectClass>(Cond, TObject, TStringList); but nevertheless, it compiles. Go figure. Share this post Link to post
Lars Fosdal 1792 Posted March 21, 2023 Changed the w line to w := Use<Word>.When(Cond, 1, 32000); That works too! Share this post Link to post
Uwe Raabe 2057 Posted March 21, 2023 You probably meant w := Use.When<Word>(Cond, 1, 32000); Share this post Link to post
Lars Fosdal 1792 Posted March 21, 2023 FFS... I need to log off. Scrolling further up in the source code, I found... type Use<T> = record public class function When(const aBool: Boolean; const WhenTrue: T; const WhenFalse: T): T; static; end; { Use<T> } class function Use<T>.When(const aBool: Boolean; const WhenTrue, WhenFalse: T): T; begin if aBool then Result := WhenTrue else Result := WhenFalse end; 1 Share this post Link to post
Lars Fosdal 1792 Posted March 21, 2023 I guess I was trying to find out which of the constructs that was more readable. Share this post Link to post
Lars Fosdal 1792 Posted March 21, 2023 28 minutes ago, Stefan Glienke said: You are thinking wrong - Delphi never infers from the lhs but only from the passed parameter. And there is usually takes the type from the first one if you have multiple with the same generic type - that is why it needs help with the 1, -2 combination. Thank you, @Stefan Glienke - that clears up the fog. It would have been nice, though - if the left side would be able to hint the type. Share this post Link to post