How to store a Integer in a TObject property and then show that value to the user?
Asked Answered
C

4

5

Of course, this piece of code will not compile. First I need to cast a TObject value to Integer. Then, read it as a string. What function should I use?

for i := 1 to 9 do begin
    cmbLanguage.Items.AddObject(Format('Item %d', [i]), TObject(i));
end;

cmbLanguage.ItemIndex := 2;

ShowMessage(cmbLanguage.Items.Objects[cmbLanguage.ItemIndex]);

Or maybe it's possible to use String instead of Integer in the first place?

Calculated answered 23/4, 2013 at 0:36 Comment(4)
What type of object is it? There's no generic TObject-to-string function.Linseed
as a note, but not an answer, I would recommend creating your own object to store in this field. After all, that's what this is intended for. Your object could include more information as needed. For example, you mention it's a list of languages. One object (i.e. TLanguage) could have properties such as "Name: String", "ID: Integer", and more.Omnirange
By the way, you're still asking how to cast it to a string, but the question mentions integer. Keep the question about integers stored in a TObject field, and string/integer conversion is the easy part (IntToStr, StrToIntDef, etc.). So the title should be more like "How to store an integer in a TObject field?"Omnirange
You were given this answer in your previous question. You should be able to find IntToStr or Format yourself.Lenticel
L
11
cmbLanguage.Items.AddObject(Format('Item %d', [i]), TObject(i));

Here you are adding an item with an "object" which is actually an integer (i) casted to a TObject.

Since you are actually storing an int in the object field, you can just cast it back to Integer, then convert that to a string:

ShowMessage(IntToStr(Integer(cmbLanguage.Items.Objects[cmbLanguage.ItemIndex])));

Note that you are not really converting anything here, you're just pretending that your integer is a TObject so the compiler doesn't complain.

Linseed answered 23/4, 2013 at 0:53 Comment(10)
How do you know the OP is storing an Integer in the Objects property?Dyaus
I was about to ask the same thing.Omnirange
The integer is the list iterator. There's still an object with unknown data.Omnirange
Well, that seems to be working. And yes, I'm storing only integers in the object associated with a ComboBox item.Calculated
Why define an object with only one integer field? Why not instead use a pointer to an integer? Is there anything in this object besides one integer?Omnirange
@JerryDodge the expression TObject(i) casts i to a TObject. There is no real object, the integer i is simply being cast to TObject.Linseed
That field is supposed to store an ID value for a language from the database.Calculated
@Linseed Right. THe OP has edited the question since I first looked at it. Makes my answer incorrect then based on that edit - ie, my assumption was wrong...Dyaus
@JerryDodge yes, OP was confused about terminology. He really just needed to cast rather than convert.Linseed
Why this works: TObject is a pointer type and pointers can be treated as NativeUInt, which is the same size (32-bit) or larger (64-bit) than Integer. This also means that you can do the same for enums, those have a maximum size of 32-bits ({$Z4})Bladdernose
H
3

If delphi xe or higher is used, I would use a generic class based on @Jerry answer.

Preparation:

unit CoreClasses;

interface

type
  IPrimitiveBox<T> = interface

    procedure setValue(value : T);
    function getValue(): T;

  end;

  TPrimitiveBox<T> = class(TInterfacedObject, IPrimitiveBox<T>)

    private
      value : T;

    public
      constructor create(value : T);

      // IPrimtiveBox<T>
      procedure setValue(value : T);
      function getValue(): T;

  end;

implementation

{ TPrimitiveBox<T> }

constructor TPrimitiveBox<T>.create(value: T);
begin
  self.value := value;
end;

function TPrimitiveBox<T>.getValue: T;
begin
  Result := value;
end;

procedure TPrimitiveBox<T>.setValue(value: T);
begin
  self.value := value;
end;

Usage (based on @Jerry example)

var
  io: IPrimitive<Integer>;

sl := TStringList.create(true);
io := TPrimitive<Integer>.create(123);
sl.addObjects(io)


io := IPrimitive<Integer>(sl.objects[4]);
ShowMessage('Integer value: '+ IntToStr(io.getValue()));
Holdup answered 29/6, 2017 at 13:49 Comment(1)
+1 @FXL for excellent versatile solution not limited by breakable assumptions like "an integer is the same size as a TObject pointer."Borchert
L
2

If you know you will be using Delphi-7 for the rest of your life stick with the TObject(i) cast. Otherwise start using proper objects, this will save you headaches when upgrading to 64 bit.

Unit uSimpleObjects;

Interface

type
   TIntObj = class
   private
      FI: Integer;
   public
      property I: Integer Read FI;
      constructor Create(IValue: Integer);
   end;

type
   TDateTimeObject = class(TObject)
   private
      FDT: TDateTime;
   public
      property DT: TDateTime Read FDT;
      constructor Create(DTValue: TDateTime);
   end;

Implementation

{ TIntObj }

constructor TIntObj.Create(IValue: Integer);
begin
   Inherited Create;
   FI := IValue;
end;

{ TDateTimeObject }

constructor TDateTimeObject.Create(DTValue: TDateTime);
begin
   Inherited Create;
   FDT := DTValue;
end;

end.

Usage:

var
  IO: TIntObj;
  SL: TStringList;

Storage:

SL := TStringList.Create(true); // 'OwnsObjects' for recent Delphi versions
IO := TIntObj.Create(123);  
SL.AddObjects(IO);

Retrieval:

IO := TIntObj(SL.Objects[4]);
ShowMessage('Integer value: '+ IntToStr(IO.I));

For Delphi-7

TIntObj := TStringList.Create;

and you have to free the objects yourself:

for i := 0 to Sl.Count-1 do 
begin
  IO := TIntObj(SL.Objects[i]);
  IO.Free;
end;
SL.Free;
Lesh answered 23/4, 2013 at 7:33 Comment(0)
O
1

You cannot simply convert an object to a string. This is something you will have to do by yourself using a method of your choice, depending on the reasoning behind it. For example, you could concatenate a string in XML format representing the data in your object. However, Delphi has absolutely no way of concatenating this data for you.


As others have pointed out, you are actually trying to cast a TObject as an Integer. This means that if you stored an integer in a TObject field, then you need to cast it back, for example Integer(MyIntObject)

Omnirange answered 23/4, 2013 at 0:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.