I'm using Delphi 2009. Is it possible to write a class helper for a generic class, i.e. for TQueue . The obvious
TQueueHelper <T> = class helper of TQueue <T>
...
end;
does not work, nor does
TQueueHelper = class helper of TQueue
...
end;
I'm using Delphi 2009. Is it possible to write a class helper for a generic class, i.e. for TQueue . The obvious
TQueueHelper <T> = class helper of TQueue <T>
...
end;
does not work, nor does
TQueueHelper = class helper of TQueue
...
end;
As near as I can tell, there's no way to put a class helper on a generic class and have it compile. You ought to report that to QC as a bug.
As documented in the Delphi help, class helpers are not designed for general purpose use and they are incorrectly perceived as having a number of limitations or even bugs as a result.
nevertheless there is a perception - incorrect and dangerous in my view - that these are a legitimate tool in the general purpose "toolkit". I have blogged about why this is wrong and subsequently about how you can go some way to mitigate the dangers by following a socially responsible coding pattern (although even this isn't bullet proof).
You can achieve much the effect of a class helper without any of these bugs or limitations or (most importantly) risks by using a hard cast to a "pseudo" class derived from the class you are trying to extend. i.e instead of:
TFooHelper = class helper for TFoo
procedure MyHelperMethod;
end;
use
TFooHelper = class(TFoo)
procedure MyHelperMethod;
end;
Just like with a "formal" helper, you never instantiate this TFooHelper class, you use it solely to mutate the TFoo class, except in this case you have to be explicit. In your code when you need to use some instance of a TFoo using your "helper" methods you then have to hard cast:
TFooHelper(someFoo).MyHelperMethod;
Downsides:
you have to stick to the same rules that apply to helpers - no member data etc (not really a downside at all, except that the compiler won't "remind you").
you have to explicitly cast to use your helper
If using a helper to expose protected members you have to declare the helper in the same unit that you use it (unless you expose a public method which exposes the required protected members)
Advantages:
Absolutely NO risk that your helper will break if you start using some other code that "helps" the same base class
The explicit typecasting makes it clear in your "consumer" code that you are working with the class in a way that is not directly supported by the class itself, rather than fudging and hiding that fact behind some syntactic sugar.
It's not as "clean" as a class helper, but in this case the "cleaner" approach is actually just sweeping the mess under the rug and if someone disturbs the rug you end up with a bigger mess than you started with.