Delphi:泛型和'is' - 运算符问题 [英] Delphi: generics and 'is'-operator problem
问题描述
根据之前的帖子,我撰写了下面的代码。请原谅这篇文章的冗长。我相信所有参与方都有更好的代码可以测试和评论。
Based on an earlier post, I've written the following code. Please excuse the verbosity of this post. I believe it's better for all parties to have the full code available to test and comment on.
program sandbox;
{$APPTYPE CONSOLE}
uses
SysUtils,
Generics.Collections;
type
TDataType = class
// Stuff common to TInt and TStr
end;
TInt = class(TDataType)
FValue: integer;
constructor Create(Value, Low, High: integer);
end;
TStr = class(TDataType)
FValue: string;
constructor Create(Value: string; Length: integer);
end;
TSomeClass = class
FIntList: TList<TInt>;
FStrList: TList<TStr>;
procedure AddToList<T: TDataType>(Element: T);
constructor Create();
procedure Free();
end;
constructor TInt.Create(Value, Low, High: Integer);
begin
inherited Create();
FValue := Value;
end;
constructor TStr.Create(Value: string; Length: Integer);
begin
inherited Create();
FValue := Value;
end;
procedure TSomeClass.AddToList<T>(Element: T);
begin
if TObject(Element) is TInt then
FIntList.Add(Element)
else if TObject(Element) is TStr then
FStrList.Add(Element);
end;
constructor TSomeClass.Create();
begin
inherited;
FIntList := TList<TInt>.Create();
FStrList := TList<TStr>.Create();
end;
procedure TSomeClass.Free();
var
SomeIntItem: TInt;
SomeStrItem: TStr;
begin
for SomeIntItem in FIntList do begin
SomeIntItem.Free();
end;
for SomeStrItem in FStrList do begin
SomeStrItem.Free;
end;
FIntList.Free();
FStrList.Free();
end;
var
Inst: TSomeClass;
begin
try
{ TODO -oUser -cConsole Main : Insert code here }
Inst := TSomeClass.Create;
Inst.AddToList(TInt.Create(100, 0, 101));
Inst.AddToList(TStr.Create('Test', 10));
Inst.Free;
except
on E:Exception do
Writeln(E.Classname, ': ', E.Message);
end;
end.
$ b TStr
在现实世界中会使用 Low,High:integer
和 code>参数。如果TObject(Element)是TInt那么
和否则如果TObject(Element)是TStr,则
有一个E2089无效类型转换 code>运行Delphi 2009.有人知道为什么会这样吗?
Note that the constructors of TInt
and TStr
in the real world would utilize the Low, High: integer
and Length: integer
parameters as well. I'm having an "E2089 Invalid typecast" at if TObject(Element) is TInt then
and else if TObject(Element) is TStr then
running Delphi 2009. Do anyone know why this happens?
编辑:请注意 TInt
和 TStr
只有两个可能10-20其他类型;否则重载是作业的工具。 :)
Please note that TInt
and TStr
are just two of possibly 10-20 other types; otherwise overloading is the tool for the job. :)
推荐答案
重新思考您的设计。您可以使用重载而不是通用类型参数,如下所示:
Rethink your design. You may just use overloading instead of a generic type parameter, like this:
procedure Add (SomeString : TString); overload;
procedure Add (SomeInt : TInt); overload;
或者如果你想使用Gamecat建议的多态性,只是传递基本类型作为参数,在该参数上使用是
:
Or if you want to use polymorphism do what Gamecat suggested and just pass the base type as the parameter, using is
on that parameter:
procedure Add (Element : TDataType);
像Rob在你的上一个问题的评论中指出的:如果你只允许两个类型并且具有基于实际类型的条件。所以仿制药在这里可能是错误的工具。
Like Rob pointed out in a comment to your previous question: it's not really generic if you allow only two types and have conditionals based on the actual type. So generics might be the wrong tool here.
希望有帮助。
这篇关于Delphi:泛型和'is' - 运算符问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!