Frank Heckenbach wrote:
Markus Gerwinski wrote:
The point is: I'm writing an API where I'd like to give the application developer the possibility to pass a method as an initialization parameter to the constructors of some objects. For example to an intermediate wrapper that turns rows of an SQL result set into objects and vice versa.
Can you expand a bit on this example? I'm not sure I can really imagine why this is really necessary? Are the methods that you pass defined in the library and/or the application? Do you need to pass arbitrarily many different methods per object type (so virtual methods won't do)? Do you need it for static and/or virtual methods?
The methods will be defined in the application. The API will provide a "method variable" parameter to pass them. I don't quite understand the question with the many different methods per object. As for static/virtual, I believe in 99% of all cases static methods will do; however, I'm not sure if the case might arise some day I need to pass a virtual (or even abstract) method.
Imagine something like this:
(* Code of the API: *)
type
tGetIntegerAttr = Function: integer; method; tSetIntegerAttr = Procedure ( aValue: integer ); method;
tDBReader = object ... Procedure addAttribute ( const aFieldName: string; aGetter: tGetIntegerAttr; aSetter: tSetIntegerAttr ); ... end (* tDBReader *);
tDBReader is, in this case, a generic object to read/write database tables and transform them into (different types of) objects.
(* Code of the application: *)
type
tPerson = object ... Function getYearOfBirth: integer; Procedure setYearOfBirth ( aValue: integer ); end (* tPerson *);
var PersonReader: pDBReader;
(* And inside some DB access initialization: *) ... PersonReader^ .addAttribute ( 'YearOfBirth', tPerson.getYearOfBirth, tPerson.setYearOfBirth ); ...
Calling addAttribute like this should, in my example, tell the PersonReader instance to take, for any given tPerson instance, the year of birth out of the 'YearOfBirth' field in the according database table and pass it to the tPerson using the setYearOfBirth method; when writing it back to the database, the PersonReader shall use the getYearOfBirth method to get the value out of the object and write it back into the field 'YearOfBirth' in the DB.
I assume getYearOfBirth and setYearOfBirth will almost always be static methods. However, as I said above, I cannot say for sure I won't some day have a situation where I need a virtual or abstract one.