1

I have a procedure in my class UserController to delete an object of class TUser based on their ID. I am wanting to make a GenericController class to be able to do this with any other class. This is my procedure:

procedure TUserController.DeleteUser(User: TUser);
begin
  if not FManager.IsAttached(User) then
    User := FManager.Find<TUser>(User.ID);
  FManager.Remove(User);
end;

I tried doing this:

procedure TGenericController.Delete(Class_: TObject; Class_ID: Integer);
    begin
      if not FManager.IsAttached(Class_) then
        Class_ := FManager.Find<Tclass(Class_)>(Class_ID);
      FManager.Remove(Class_);
    end;

But I receive this error:

[dcc32 Error] GenericController.pas(36): E2531 Method 'Find' requires explicit type argument(s)

This the method Find from TMS Aurelius:

function TObjectManager.Find<E>(IdValue: Variant): E;
begin
  Result := E(Find(TClass(E), IdValue));
end;
Artur_Indio
  • 736
  • 18
  • 35

1 Answers1

2

Generics are resolved at compile-time but Tclass(Class_) (which can be replaced with Class_.ClassType instead) is not known until run-time, so it cannot be used as a Generic parameter value.

Update: As SirRufo tried to explain in comments, you could do something more like this:

procedure TGenericController.Delete<E>(Obj: E; Obj_ID: Integer);
begin
  if not FManager.IsAttached(Obj) then
    Obj := FManager.Find<E>(Obj_ID);
  FManager.Remove(Obj);
end;

For instance, if TUserController derives from TGenericController, then DeleteUser() could do this:

procedure TUserController.DeleteUser(User: TUser);
begin
  inherited Delete<TUser>(User, User.ID);
end;
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770