Delphi: determine actual type of a generic?

2020-04-06 00:57发布

问题:

Is there any way to determine the type of a variable passed as an argument to a method? Consider the class:

TSomeClass = class
  procedure AddToList<T: TDataType; U: TListClass<T>>(Element: T; List: U);
end;

with the method implementation

procedure TSomeClass.AddToList<T, U>(Element: T; List: U);
begin
  if Element is TInt then
    List.AddElement(TInt.Create(XXX))
  else if Element is TString then
    List.AddElement(TString.Create(YYY));
end;

where TInt.Create() and TString.Create() have different sets of arguments, yet, they both inherit from TDataType.

Now, I know the is-operator can't be used like this, but is there a legal alternative that does what I'm asking here?

回答1:

Not being able to use the is operator here is a known issue, but there's a pretty simple workaround.

  if TObject(Element) is TInt then
    List.AddElement(TInt.Create(XXX))

Also, since the type of a generic is part of the class and is known at compile-time, you might be better off restructuring your code. Make two different generic classes, one of which accepts a TInt as its <T> parameter, and the other of which accepts a TString. Put the type-specific functionality into them at that level, and have them descend from a common ancestor for shared functionality.



回答2:

This question I asked some time ago

Conditional behaviour based on concrete type for generic class

might be of interest, especially if you want to use not only TObject descendants but also primitive types in your conditionals.