Delphi:确定泛型的实际类型?

6
有没有办法确定作为方法参数传递的变量的类型?考虑以下类:

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

使用方法实现

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;

TInt.Create()和TString.Create()拥有不同的参数集,但它们都继承自TDataType。

现在,我知道is运算符不能像这样使用,但是否有合法的替代方案可以实现我在这里所要求的功能呢?


4
如果你在通用代码中的第一件事情是为每个可能的通用值编写特定类型的代码,那么你就不再写通用代码了。这不是使用泛型的正确方式。 - Rob Kennedy
3
感谢你的意见,Rob。当我在Stack Overflow(和其他地方)发问时,我通常会提出我的真实代码的简化版本。以我的经验来看,提取问题的本质比展示真实世界的代码更有用,因为那些代码通常更加复杂。因此,请将上述代码视为更大问题的说明。顺便说一下:我很想了解替代上述代码的方法。请查看我的后续问题:http://stackoverflow.com/questions/1761487/delphi-generics-and-is-operator-problem。我期待对那个帖子的任何意见! :) - conciliator
2个回答

5

无法在这里使用is运算符是已知的问题,但有一个非常简单的解决方法。

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

此外,由于泛型的类型是类的一部分并在编译时已知,您最好重新构建代码。创建两个不同的泛型类,其中一个接受TInt作为其<T>参数,另一个接受TString。将类型特定的功能放入它们的级别,并让它们从一个共同的祖先下降以实现共享功能。

谢谢Mason!但是我遇到了“E2089无效类型转换”错误。你知道为什么吗?我上一篇帖子可能表达不清楚,但TInt和TString都是从TDataType派生出来的,但它们在TInt和TString级别上有所不同(特别是它们的构造函数)。这就是你的意思,对吧?无论如何 - 约束被放置在尽可能靠近TInt和TString的位置,以确保最佳功能。 - conciliator
你在哪一行代码上遇到了错误?我没有你的代码可以测试,但是我写了一个简单的测试,将其转换为TObject对我来说很好用。 - Mason Wheeler
在我的原始帖子中,我正在处理一个更复杂的设计,但是给出了上面呈现的示例,因为它捕捉到了我遇到的基本问题。因此,当要求提供整个源代码时,我不得不从头开始编码。它看起来有点不同,但我仍然遇到了类型转换问题。我应该将其作为单独的问题发布,还是作为您帖子的答案发布? - conciliator
最好将其作为一个单独的问题发布。但要记住 Rob Kennedy 在他上面的评论中写的话。他说得很有道理。 - Mason Wheeler
谢谢Mason。昨天我必须要离开,这就是延迟的原因... 我已经回复了Rob的评论(附上了新帖子的链接)。我相信Rob有一点,我很想听听这个问题的一些反馈。你认为何时使用泛型是有意义的?TInt和TStr示例仅是两种特定的数据类型。想象一下,您还有15-20个其他数据类型... 我认为这构成了泛型合理的用法。你怎么看? - conciliator

4

1
+1 你救了我的一天,因为我需要链接的答案来启用枚举类型的通用转换函数。 - Marjan Venema

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接