Miguel Febres
Miguel Febres

Reputation: 2183

Type parameter 'T' must be a class type

I am writing a small helper class for REST operations. One of my main goals is to provide automatic casting from the body response in JSON to a specific object using generics.

This is how one of the functions look in the helper class:

function RESTServiceCallHelper.ExecuteAsObject<TObj>(resource: string): TObj;
var
 RestRequest: TRESTRequest;
 obj: TObj;
begin
  PrepareRequest(RestRequest, resource);
  RestRequest.Execute;
  obj := TJson.JsonToObject<TObj>(RestRequest.Response.Content);
  result:=obj;
end;

And here is how I am trying to use it:

type

   TPartnerCreditInfo   = class
      FlCreditClassDesc: string;
      FCppID: string;
      FCreditClass: string;
      FCreditClassDesc: string;
      FCreditLimit_CurrencyCode: string;
      FCreditLimit: double;
      FAmountBalance: double;
      FAmountBalance_CurrencyCode: string;
      FAmountBalanceLast: double;
      FAmountBalanceLast_CurrencyCode: string;
   end;

procedure TModuleX.CallAPIS;
var
  lRESTHelper : TrpRESTServiceCallHelper;
  pc: TPartnerCreditInfo;
begin
  lRESTHelper:= TrpRESTServiceCallHelper.Create('https://mydomain/api');
  lRESTHelper.AddQueryStringParam('param1','paramvalue');

  pc:=lRESTHelper.ExecuteAsObject<TPartnerCreditInfo>('resource');
  showmessage(pc.FCppID);
end;

The issue I am facing is this at compilation time:

obj := TJson.JsonToObject<TObj>(RestRequest.Response.Content);
[dcc32 Error] RESTServiceCallObj.pas(99): E2511 Type parameter 'T' must be a class type

According to the documentation the T parameter for JsonToObject function must be a class and TPartnerCreditInfo is a class too. Why is TPartnerCreditInfo not being recognized?

Upvotes: 2

Views: 718

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 595319

The T Generic parameter of TJson.JsonToObject() has been marked with the class and constructor constraints. As such, the TObj Generic parameter of your ExecuteAsObject() function needs to be marked with the same constraints:

function ExecuteAsObject<TObj: class, constructor>(resource: string): TObj;

Those constraints inform the compiler that T/TObj are required to be a class type that has a parameterless Create() constructor, which is what allows JsonToObject() to create a new object instance of the type passed to T/TObj.

Upvotes: 7

Related Questions