Как преобразовать переменную определенного типа в общий T в Delphi? - PullRequest
0 голосов
/ 11 мая 2018

В зависимости от фактического типа T, я хочу вернуть конкретное значение; вот упрощенный пример (обертка записи вокруг некоторого объекта):

function TMyRec.TryGet<T>(const Default: T): T;
begin
  if TypeInfo(T) = TypeInfo(TMyObject) then
    Result:= FMyObject {E2010 Incompatible types}
  else Result:= FMyObject.TryGet<T>(Default);
end;

Понятно, что я не могу назначить ничего, кроме T для Result, и as T или T() не работают, когда T не ограничен class ...

Также невозможно выполнить перегрузку, которая отличается только общим ограничением:

function TryGet<T: TMyObject>(const Default: T): T; overload;
{...}
Result:= FMyObject as T; {here it would work}

Чтобы помочь понять обсуждение в комментариях ниже, вот пример из моего редактирования:

function TMyRec.TryGet<T>(const Default: T): T;
begin
  if TypeInfo(T) = TypeInfo(TMyObject) then Result:= FMyObject
  //else ...
  else Result:= Default;
end;

Ответы [ 2 ]

0 голосов
/ 11 мая 2018

Я считаю, что это лучший метод (по крайней мере, с точки зрения производительности) для достижения того, чего вы хотите.

type 
  PMyObject = ^TMyObject;

function TMyRec.TryGet<T>(const Default: T): T;
begin
  if TypeInfo(T) = TypeInfo(TMyObject) then 
    PMyObject(@Result)^ := FMyObject
  else if TypeInfo(T) = TypeInfo(Integer) then 
    PInteger(@Result)^ := 1
  //else ...
  else
    Result := Default;
end;
0 голосов
/ 11 мая 2018

Единственный способ, который я нашел, это использовать System.Rtti.TValue (исключение, если неправильный тип):

Result:= TValue.From(FMyObject).AsType<T>

или намного короче ;-) с автоматическим типом (возвращает false, если неправильный тип; вы можете проигнорировать это здесь, потому что вы уже проверили TypeInfo):

TValue.From(FMyObject).TryAsType(Result)

Предложение: переосмыслить свою концепцию; есть опасения , что дженерики не могут быть хорошим решением, но мы не можем сказать, не зная больше об истории вопроса.

...