Depending on the actual type of T, I want to return a specific value; here a simplified example (a record wrapper around some object):
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;
It's clear that I cannot assign anything other than T
to Result
, and as T
or T()
don't work, when T
is not restricted to class
...
It's also not possible to do an overload which differs only in the generic restriction:
function TryGet<T: TMyObject>(const Default: T): T; overload;
{...}
Result:= FMyObject as T; {here it would work}
To help understand the discussion in the comments below, here is the example from before my edit:
function TMyRec.TryGet<T>(const Default: T): T;
begin
if TypeInfo(T) = TypeInfo(TMyObject) then Result:= FMyObject
//else ...
else Result:= Default;
end;
I believe this is the best method (performance-wise at least) to achieve what you want.
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;
The only way I found is using System.Rtti.TValue
(exception if wrong type):
Result:= TValue.From(FMyObject).AsType<T>
or much shorter ;-) with automatic type (returns false if wrong type; you could ignore that here because you already checked TypeInfo):
TValue.From(FMyObject).TryAsType(Result)
Suggestion: rethink your concept; there are concerns that generics might not be a good solution, but we cannot tell without knowing more about the background.
I'm using Delphi XE5.
Change yoru sample to this:
function TryGet<T: class>(const Default: T): T; overload;
{...}
Result:= FMyObject as T; {here it will work}
The change is TMyObject
to class
. When you are not "class" it, you will get the compiler error E2089.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.