When developing libraries, I often resort to the following template, which I do not like, since it leads to a large number of ticks.
The main template:
Code using the library passes the object to the library, then the library passes the object back to the calling code. The calling code is forced to return an object, since the library returns a generic type. (Example abbreviated code below)
The library defines the following objects and functions:
TThing = Class End; TThingProcessor = Class Public Function CreateThing : TThing; Virtual; Abstract; Procedure ProcessThing (Thing : TThing); Virtual; Abstract; End; Procedure DoEverything (Processor : TThingProcessor);
Then the calling code uses the library, overriding the objects and calling DoEverything, as follows:
TMyThing = Class(TThing) Public X : Integer; End; TMyThingProcessor = Class(TThingProcessor) Public XSum : Integer; Function CreateThing : TThing; Override; Procedure ProcessThing (Thing : TThing); Override; End; Function TMyThingProcessor.CreateThing : TThing; Begin Result := TMyThing.Create; End; Procedure TMyThingProcessor.ProcessThing (Thing : TThing); Begin XSum := XSum + (Thing As TMyThing).X; //Here is the problem, the caller is forced to cast to do anything End;
The processor class is also a TThing factory. The library guarantees that it will only pass TThings to the corresponding twingprocessor that created them, so it works, but is not type safe. Although the code above is a little silly in that it doesn't actually do anything, it shows why ProcessThing cannot just be switched to TThing and be polymorphic - the XSum variable needs to be updated.
How can I restructure the code to make the throw unnecessary? I need to save the library code separately, but be able to accept any types.
Edit: Due to the proposal, I changed hard-cast to as-cast, so it will at least throw an exception instead of failing in case of inappropriate types.