Dmitry Onoshko 0 Posted Sunday at 08:24 AM Consider a container: type TCustomItem = class protected FContainer: // ??? end; TCustomContainer<T: TCustomItem> = class abstract protected FItems: TArray<T>; ... procedure HandleItemNotification(AItem: T); end; The items are supposed to be classes derived from common ancestor in parallel with containers: type TFooItem = class(TCustomItem); TFooContainer = class(TCustomContainer<TFooItem>); TBarItem = class(TCustomItem); TBarContainer = class(TCustomContainer<TBarItem>); An item should store a pointer to its container for notification purposes. But TFooItem should never be used with TBarContainer or vice versa. I seem to get closer when I declare the TCustomItem as inner class: type TCustomContainer<T: TCustomItem> = class abstract public type TCustomItem = class protected FContainer: TCustomContainer<T>; end; protected FItems: TArray<T>; ... procedure HandleItemNotification(AItem: T); end; But then, when I call procedure TCustomContainer<T>.TCustomItem.SomeMethod; begin ... FContainer.HandleItemNotification(Self); ,,, end; inside TCustomItem method, I get “Incompatible types: T and UnitName.TCustomContainer<T>.TCustomItem”. Is this even possible? Share this post Link to post
havrlisan 24 Posted Sunday at 09:05 AM 12 minutes ago, Dmitry Onoshko said: type TCustomContainer<T: TCustomItem> = class abstract public type TCustomItem = class protected FContainer: TCustomContainer<T>; end; protected FItems: TArray<T>; ... procedure HandleItemNotification(AItem: T); end; But then, when I call procedure TCustomContainer<T>.TCustomItem.SomeMethod; begin ... FContainer.HandleItemNotification(Self); ,,, end; inside TCustomItem method, I get “Incompatible types: T and UnitName.TCustomContainer<T>.TCustomItem”. It is not possible to define TCustomContainer<T: TCustomItem> if TCustomItem is its internal public type. This only compiles (up to your error) because there is another TCustomItem defined outside that class. Doing this with classes only is impossible. You cannot have both a T that is a TCustomItem within TCustomContainer<T> and a FContainer that is a TCustomContainer<T> within TCustomItem. The relation cannot be bi-directional in this scenario. A closer implementation to what you're trying to achieve is possible with interfaces, but that comes with its own set of issues. This post has an example of what you're trying to achieve with interfaces: Also, IMO it is not a good idea to couple your classes like you're trying to do here. A TCustomItem should not directly call the TCustomContainer's HandleItemNotification; you should handle that either via an observer pattern or with events. 1 Share this post Link to post