Thoughts from Dan Miser RSS 2.0
 Thursday, February 16, 2006
There are times when you get painted into a corner. Some times, you paint yourself in, and some times, you get painted in by others. If you do it to yourself, it is much easier to get out by just changing all of the things needed to get out of the jam. Other times, your hands are tied and you can only make changes to specific areas of code, like the implementation section. A couple of reasons for this would be to preserve binary compatbility of a published interface for your framework, or a 3rd party component relies on that dcu compatibility of another 3rd party. Given all of the above, what do you do if you want to add a property to an existing class without changing the interface section of that unit? I came up with the following hack to get this done, but be cautioned, this is definitely not for the squeamish! :)

Let's say you have a setup like the following:


unit uExtenderTypes;

interface

type
  TType = class
  private
    FID: integer;
  public
    procedure Display;
    property ID: integer read FID write FID;
  end;

function GetType: TType;

implementation

uses
  SysUtils, Dialogs;

var
  gblType: TType = nil;

function GetType: TType;
begin
  if gblType = nil then
    gblType := TType.Create;
  Result := gblType;
end;

procedure TType.Display;
begin
  ShowMessage(IntToStr(ID));
end;

finalization
  if Assigned(gblType) then
    FreeAndNil(gblType);
end.

As time passes, you realise you want to only do the ShowMessage some of the time, and to do this you think a CanDisplay property would be perfect on the TType class. But remember, you can't change the interface section. You can add code like this to get things ready (only the changed section is listed here):


{$M+}
type
  TDerivedType = class(TType)
  private
    FCanDisplay: boolean;
  published
    property CanDisplay: boolean read FCanDisplay write FCanDisplay;
  end;
{$M-}

function GetType: TType;
begin
  if gblType = nil then
    gblType := TDerivedType.Create;
  Result := gblType;
end;

procedure TType.Display;
begin
  if (Self is TDerivedType) and TDerivedType(Self).CanDisplay then
    ShowMessage(IntToStr(ID));
end;

Note that the main changes are to add the new class - derived from the base class - in the implementation section; update the singleton TType return function; and update the Display method to conditionally display the message.

In order to set this property, we will rely on RTTI since callers outside the scope of this unit will have no idea what the TDerivedType is. The code for this would look similar to this:


procedure SetCanDisplay(t: TType; Value: boolean);
begin
  if IsPublishedProp(t, 'CanDisplay') then
    SetOrdProp(t, 'CanDisplay', ord(Value));
end;

procedure TForm3.btnDerivedClick(Sender: TObject);
var
  t: TType;
begin
  t := GetType;
  t.ID := 30;

  SetCanDisplay(t, true);
  try
    t.Display;
  finally
    SetCanDisplay(t, false);
  end;
end;

Obviously, this technique should only be used as a last result. However, it can get you out of that tight spot for a little while, and the changes are pretty well self-contained so you can do it right when building the next version.

Thursday, February 16, 2006 8:57:00 PM (Central Standard Time, UTC-06:00)  #    Comments [2] -

Tracked by:
http://9nt-information.info/08094823/index.html [Pingback]
http://9np-information.info/09526828/index.html [Pingback]
http://9nr-information.info/69138428/index.html [Pingback]
http://9ne-information.info/21150166/lorenna-mckennir-san-tiago-mp3-download.htm... [Pingback]
http://9nd-information.info/06547899/city-of-boston-filing-business-certificate.... [Pingback]
http://9na-information.info/25114549/index.html [Pingback]
http://9nq-information.info/62600508/index.html [Pingback]
http://9ne-information.info/96661051/index.html [Pingback]
http://9nm-information.info/95021500/index.html [Pingback]
http://9nc-information.info/69596818/index.html [Pingback]
http://9nd-information.info/39044273/american-car-performance-parts.html [Pingback]
http://9nv-information.info/47549673/96-cadillac-service-codes.html [Pingback]
http://9oo-information.info/30866300/index.html [Pingback]
http://9oe-information.info/83425005/index.html [Pingback]
http://9oq-information.info/65428386/texas-safety-company.html [Pingback]
http://9og-information.info/07839579/index.html [Pingback]
http://9qr-information.info/40130532/index.html [Pingback]
http://9oo-information.info/33520416/index.html [Pingback]
http://9oa-information.info/85102302/index.html [Pingback]
http://9oe-information.info/86021284/six-toed-cat-breeds.html [Pingback]
http://9of-information.info/53240628/index.html [Pingback]
http://9ou-information.info/78257521/lea-sports.html [Pingback]
http://9or-information.info/27475676/nbaa-management-guidebook.html [Pingback]
http://9og-information.info/95810206/car-park-concession.html [Pingback]
http://9rf-information.info/70192191/index.html [Pingback]
http://9sm-information.info/54977861/basal-cell-carcinoma.html [Pingback]
http://9rq-information.info/31685333/the-movie-morcow-zero.html [Pingback]
http://9ry-information.info/95198580/better-than-chess-game.html [Pingback]
http://9ra-information.info/94769308/index.html [Pingback]
http://9ro-information.info/62095024/hawaiian-music-clips.html [Pingback]
http://9sg-information.info/15232417/pannello-gres.html [Pingback]
http://9uafl-le-informazioni.info/26068778/index.html [Pingback]
http://9uaef-le-informazioni.info/64948329/fuji-foto.html [Pingback]
http://9uael-le-informazioni.info/68171057/index.html [Pingback]
http://9uafs-le-informazioni.info/15375771/index.html [Pingback]
http://9uaft-le-informazioni.info/95705902/forno-pizzeria-canna-fumaria-vendita.... [Pingback]
http://9uafq-le-informazioni.info/92812804/farmacista-psoriasi.html [Pingback]
http://9uaer-le-informazioni.info/34597820/index.html [Pingback]
http://9uafd-le-informazioni.info/46489188/index.html [Pingback]
http://9uaep-le-informazioni.info/30476427/index.html [Pingback]
http://9uafi-le-informazioni.info/36320190/index.html [Pingback]
http://9uafe-le-informazioni.info/79475007/mappa-concettuale-della-rivoluzione-i... [Pingback]
http://9uahs-le-informazioni.info/46290878/index.html [Pingback]
http://9uahn-le-informazioni.info/93162434/co-te.html [Pingback]
http://9uahk-le-informazioni.info/79820941/configurazione-apache2.html [Pingback]
http://9uagr-le-informazioni.info/67548007/index.html [Pingback]
http://9uahp-le-informazioni.info/77301711/index.html [Pingback]
http://9uahk-le-informazioni.info/49516320/scarico-moto-leo-vinci.html [Pingback]
http://9uagq-le-informazioni.info/98667303/index.html [Pingback]
http://9uagd-le-informazioni.info/96918960/index.html [Pingback]
http://9uahi-le-informazioni.info/42207445/index.html [Pingback]
http://9uagh-le-informazioni.info/70435901/index.html [Pingback]
Friday, February 17, 2006 3:07:00 AM (Central Standard Time, UTC-06:00)
Nice hack! ;)
Friday, February 24, 2006 12:27:00 PM (Central Standard Time, UTC-06:00)
RTTI tunneling loophole hack, cool.
Jeff Chojnacki
Comments are closed.
Navigation
Archive
<August 2008>
SunMonTueWedThuFriSat
272829303112
3456789
10111213141516
17181920212223
24252627282930
31123456
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2008
Dan Miser
Sign In
Statistics
Total Posts: 307
This Year: 22
This Month: 1
This Week: 1
Comments: 604
All Content © 2008, Dan Miser
DasBlog theme 'Business' created by Christoph De Baene (delarou)