I have the following code. I want to override the Notify method of the base base list on this to be able to create an event on the modification of the list.
TDescendantList = class(TObjectList<TSomeclass>)
private
<...>
protected
procedure Notify(const Value: T;
Action: TCollectionNotification); override;
<...>
end;
If I put Value: T
I get an "Undeclared identifier" on T.
If is Value: TSomeClass
I get the "Declaration of 'Notify' differs from previous declaration".
Notify
is a protected method of TObjectList<T: class>
. This method does not appear on overriding list of the XE2 IDE.
That's some way to implement this or I need to use another approach as this is an proverbial brick wall?
You cannot inherit a generic type. // class Derived20 : T {}// NO!
You can't inherit from the generic type parameter. C# generics are very different from C++ templates. Inheriting from the type parameter requires the class to have a completely different representation based on the type parameter, which is not what happens with . NET generics.
Similar to John Carpenter's answer, you can override the generic method with the same generic method, but simply use the as operator to check and cast it to the desired type. This has the added benefit of using null-testing to check if the conversion worked.
You can create your own generic interfaces, classes, methods, events, and delegates. You may create generic classes constrained to enable access to methods on particular data types. You may get information on the types used in a generic data type at run-time by means of reflection.
If your descendant class is fixing the generic type then you have to use that fixed type in place of T. In your case :
protected
procedure Notify(const Value: TSomeclass;
Action: TCollectionNotification); override;
is the correct way to declare this function.
The error :
Declaration of 'Notify' differs from previous declaration
is a regrettable case of the Delphi RTL duplicating type names in different units.
The unit System.Classes
defines
TCollectionNotification = (cnAdded, cnExtracting, cnDeleting);
and System.Generics.Collections
defines
TCollectionNotification = (cnAdded, cnRemoved, cnExtracted);
Almost certainly you have Generics.Collections
declared before Classes
in your uses
clause and the compiler is resolving the undesired version of TCollectionNotification
.
To fix it, either reorganize your uses
clauses so that Generics.Collections
comes after Classes
or use a fully qualified type name, ie :
procedure Notify(const Value: TSomeClass;
Action: Generics.Collections.TCollectionNotification); override;
The lesson with a differs from previous declaration
error is to methodically check your types. Ctrl+CLICK on the type identifier will take you to the definition of the type the compiler is using.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With