Jump to content
Larry Hengen

Interface Completion

Recommended Posts

When re-factoring code so I can introduce an interface I need to have properties implemented on the interface for compatibility to the existing implementation, so I need setters and getters to be implemented.  I f I copy all the property declarations from the existing class and change the Field references to Get/Set methods, I would like to have the Delphi IDE generate the Get/Set methods the same way class completion does so for classes. Is there a way in the Delphi IDE to get Interface declarations "completed" IOW the method declarations generated in the interface?

 

Here is some sample code to illustrate the issue:

  ICRSAMClient = interface(IInterface)
    ['{FF3CA485-A0CA-4ED6-8D70-9A757E8E9E0E}']
    //property Getters/Setters
    function GetCRSAMData :TCRSAMDataArray;
    procedure SetCRSAMData(Value: TCRSAMDataArray);
    function GetCRSAMDataCount :integer;
    procedure SetCRSAMDataCount(const Value: integer);
    function Q22Search(Param: TCRSAMSearchParam; Threshold, RowLimit: double): boolean;

    property UserId: string read GetUserID write SetUserID;                                       // User ID (authorization)
    property UserFirstName: string read GetUserFirstName write SetUserFirstName;                  // User First Name (authorization)
    property UserLastName: string read GetUserLastName write SetUserLastName;                     // User Last Name (authorization)
    property SendingApplication: string read GetSendingApplication write SetSendingApplication;   //
    property SendingFacility: string read GetSendingFacility write SetSendingFacility;            //
    property ProcessingID: string read GetProcessingID write SetProcessingID;                     //
    property Data: TCRSAMDataArray read GetCRSAMData write SetCRSAMData;                          // CRS returned data structure
    property DataCount: integer read GetCRSAMDataCount write SetCRSAMDataCount;                   // Data structure object count
  end;

Share this post


Link to post

Are you asking if there's a way to have the Getter and Setter methods declared automatically from the property declaration in the interface declaration?

 

E.g. you have:

type

  IMyInterface = interface

    property Foo: string read GetFoo write SetFoo;

  end;

 

and you want to end up with:

 

type

  IMyInterface = interface

    function GetFoo: string;
    procedure SetFoo(const Value: string);

    property Foo: string read GetFoo write SetFoo;

  end;

 

AFAIK there's no standard way to have the getters and setter automatically declared 😞

What I usually do, if there's a lot of them, is to just copy the property declaration to an implementing class, use class completion on that to generate the getters and setters and then copy the declaration of those back to the interface declaration.

Share this post


Link to post

In case you give MMX Code Explorer a try: it has an Extract Interface refactoring.

 

Given this class declaration

type
  TMyClass = class
  private
    FNewProp: Integer;
    function GetNewProp: Integer;
    procedure SetNewProp(const Value: Integer);
  public
    procedure NewMethod;
    property NewProp: Integer read GetNewProp write SetNewProp;
  end;

select the property and method in the members view of the MMX Code Explorer window and in the context menu select Refactorings - Extract Interface. In the following dialog enter the interface name, GUID etc. and you end up with this:

  IMyInterface = interface(IInterface)
  ['{8431B2B9-8D15-4308-BF08-26AB2BA4960F}']
    function GetNewProp: Integer;
    procedure NewMethod;
    procedure SetNewProp(const Value: Integer);
    property NewProp: Integer read GetNewProp write SetNewProp;
  end;

 

  • Like 2
  • Thanks 1

Share this post


Link to post
20 hours ago, Anders Melander said:

Are you asking if there's a way to have the Getter and Setter methods declared automatically from the property declaration in the interface declaration?

Yes that is exactly what I am asking.  I too have traditionally used class completion on the class and then copied the Getter/Setters to the interface, but ideally the IDE limitations should not prevent you from working the way you wish too, it should facilitate most use cases.  You should not have to implement an interface on a class in order to define the interface.

Share this post


Link to post

 

I have created some code templates that generate the getter/setter methods as part of the property declaration.

They effectively mimic the propf, proprof and a few others.  I find it quite quick.

 

eg, i'll type ipropg<ctrl-j> and just have to enter the name of the Property and its type and I'll end up with something like this:

 

function Get_Test: string;
property Test: string read Get_Test;

 

All I need to type was "Test" and string (although I default the type to string so I didn't need to type that).

 

I have a iprop<ctrl-j> shortcut which does that same but adds the setter method too:

function Get_Test2: Integer;
procedure Set_Test2(const Value: Integer);
property Test2: Integer read Get_Test2 write Set_Test2;

I just had to type Test2 and Integer accordingly...

 

Share this post


Link to post

Sure.

I've attached the 6 or so that I use regularly... 

You can adopt/change/add as suits your requirements...

My template xml files reside in My Documents\Embarcadero\Studio\Code_Templates\Delphi

 

Example:

<?xml version="1.0" encoding="utf-8" ?>

<codetemplate	xmlns="http://schemas.borland.com/Delphi/2005/codetemplates"
				version="1.0.0">
	<template name="ipropg" invoke="auto">
		<point name="propertyName">
			<text>
				PropertyName
			</text>
			<hint>
				property name
			</hint>
		</point>
		<point name="propertyType">
			<hint>
				property type
			</hint>
			<text>
				string
			</text>
		</point>
		<description>
			interface property (with getter)
		</description>
		<code language="Delphi" context="typedecl" delimiter="|"><![CDATA[
function Get_|propertyName|: |propertyType|;
property |propertyName|: |propertyType| read Get_|propertyName|; |end|
]]>
		</code>
	</template>
</codetemplate>

 

code_templates.zip

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×