views:

188

answers:

2

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?

+4  A: 

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.

Mason Wheeler
Thanks Mason! However, I'm getting an "E2089 invalid typecast" error. Do you know why? And I might've been unclear in my last post, but TInt and TString both descend from TDataType, but they differ at TInt and TString level (in particular their constructors). That's what you meant, right? Anyway - the constraint is put as "near" TInt and TString as possible to ensure optimal functionality.
conciliator
What line are you getting the error on? I don't have your code to test on, but I wrote up a simple test and casting to TObject works fine for me...
Mason Wheeler
In my original post, I was working with a more complex design, but gave the example as presented above, because it captures the essential problem I'm having. So, when asked for the entire source, I had to code it from "scratch". It looks a little different, but I'm still having the typecast-issue. Should I post it as a separate question, or as an answer to your post?
conciliator
It would probably be better to post it as a separate question. But bear in mind what Rob Kennedy wrote in his comment above. He's got a good point.
Mason Wheeler
Thanks Mason. I had to run yesterday, so that's the reason for the delay... I've commented Rob's comment (together with the link to the new post). I'm sure Rob has a point, and I would love to get some feedback on the matter. When do you believe it makes sense to use generics? The TInt and TStr examples are only two specific data types. Imagine you have 15-20 others as well... I believe that constitutes a sensible use of generics. What do you think?
conciliator
A: 

This question I asked some time ago

http://stackoverflow.com/questions/805931/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.

Smasher