Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2009-07

Is there a way to avoid class casting?

4 messages · 2 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Horacio Jamilis

Hi,

I am building from some time a OPF, that is working fine for me, but I´d like to avoid the big amount of castings I am using...

I have one class on each unit.
Each class contains the properties that represent´s it :-) One property kind is TLinkedObjectProperty. This class has a property that returns a TObject, pointing to the object the property is referencing...
TLinkedObjectProperty has another property called LinkedObjectClass that has the class of the linked object.

Is there a way that, each time I reference (by code) ... mylinkedproperty.obj ... this obj is taken by the compiler of its linkedobjectclass class?
so, I can use... mylinkedproperty.obj.[prop] ... beeing [prop] any property of the object that is of class LinkedObjectClass, and avoiding to type TMyLinkeddObjectClass(mylinkedproperty.obj).[prop] ???

Sorry for my poor english and I hope you understand what I mean.

Thanks in advance

Horacio from Argentina.

Graeme Geldenhuys
to Horacio Jamilis
Horacio Jamilis wrote
so, I can use... mylinkedproperty.obj.[prop] ... beeing [prop] any property of the object that is of class LinkedObjectClass, and avoiding to type TMyLinkeddObjectClass(mylinkedproperty.obj).[prop] ???

You can define TMyLinkeddObjectClass and override the property types so casting is only done in that class's implementation. All your instances of TMyLinkeddObjectClass doesn't have to do casting then.

eg:

   // you base class of your OPF framework.
   TtiObjectList = class(TtiObject)
   private
   protected
     function    GetItems(i: integer): TtiObject; virtual;
     procedure   SetItems(i: integer; const Value: TtiObject); virtual;
   public
     property    Items[i:integer]: TtiObject read GetItems write SetItems;
     function    Add(const AObject: TtiObject): integer; virtual;
   published
   end;
   // Your custom object list class which defines correct class types
   TMyLinkeddObjectClassList = class(TtiObjectList)
   private
   protected
     function    GetItems(i: integer): TMyLinkeddObjectClass; reintroduce;
     procedure   SetItems(i: integer; const Value:
TMyLinkeddObjectClass); reintroduce;
   public
     property    Items[i:integer]: TMyLinkeddObjectClass read GetItems
write SetItems;
     function    Add(const AObject: TMyLinkeddObjectClass): integer;
reintroduce;
   published
   end;

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://opensoft.homeip.net/fpgui/
Horacio Jamilis
to Graeme Geldenhuys

Thanks for the answer but... the problem is more complicated...

Even if I create a descending class for each TLinkedObjectProperty... I will not be able to use them...

Because I have 1 class per unit, y can´t have references to the item class in the interfase of the new class, because this way I will have a lot of circular references

I don´t see a solution... except keeping casting :-(

Horacio from Argentina

Graeme Geldenhuys wrote 11 lines
Horacio Jamilis wrote: > so, I can use... mylinkedproperty.obj.[prop] ... beeing [prop] any > property of the object that is of class LinkedObjectClass, and > avoiding to type TMyLinkeddObjectClass(mylinkedproperty.obj).[prop] ??? You can define TMyLinkeddObjectClass and override the property types so casting is only done in that class's implementation. All your instances of TMyLinkeddObjectClass doesn't have to do casting then. Regards, - Graeme -
Graeme Geldenhuys
to Horacio Jamilis
Horacio Jamilis wrote
Even if I create a descending class for each TLinkedObjectProperty... I will not be able to use them...

Could you post the Interface section of your classes and mention what units they are in. Alternatively look at the tiOPF framework and the source code examples. The following website mentions how to get the source code. http://tiopf.sourceforge.net

----------[ tiObject.pas ]---------------------

  // you base class of your OPF framework.
  TtiObjectList = class(TtiObject)
  ...
  end;

The following is custom classes in your application.

----------[ customer.pas ]---------------
TCustomerList = class(TtiObjectList)
...

  end;

-----------[ orders.pas ]--------------
TOrderList = class(TtiObjectList)
...

  end;

If you want many-to-many relationships (though you did not mention this in your first posting), then you need to use base classes and to casting. Or pick a "master" class our of the two relationships. The "master" class, lets say TCustomer will contains TOrderList property. But the TOrderList will contain base class and casting. This minimizes casting.

Or use something like the Relationship Manager design pattern. Relationship Manager can also be found in the tiOPF source code:

https://tiopf.svn.sourceforge.net/svnroot/tiopf/tiOPF2/Trunk/Quarantine/RelationshipManager

As another alternative, you can implement relationships using Interfaces. The class definition will only mention the Interface name, not the concrete class type.

I don´t see a solution... except keeping casting :-(

Like I said, if you can post the interfaces definitions of your classes, it will be easier to see how you use your classes and what solution can be applied. Remember to also mention which class definitions are in which units.

Regards,
- Graeme -

________________________________________________
fpGUI - a cross-platform Free Pascal GUI toolkit
http://opensoft.homeip.net/fpgui/