德尔福:泛型和'是'运算符问题

con*_*tor 2 delphi generics casting

基于之前的帖子,我编写了以下代码.请原谅这篇文章的详细内容.我相信所有各方都可以使用完整的代码进行测试和评论.

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.
Run Code Online (Sandbox Code Playgroud)

注意的构造TIntTStr在现实世界将利用Low, High: integerLength: integer参数,以及.我有一个"E2089无效的类型转换"在if TObject(Element) is TInt thenelse if TObject(Element) is TStr then运行德尔福2009年千万人知道为什么会出现这种情况?

编辑:请注意,TInt并且TStr只是可能10-20其它类型的两个; 否则重载是工作工具.:)

jpf*_*ius 7

重新思考你的设计.您可以只使用重载而不是泛​​型类型参数,如下所示:

procedure Add (SomeString : TString); overload;
procedure Add (SomeInt : TInt); overload;
Run Code Online (Sandbox Code Playgroud)

或者,如果你想使用多态性做Gamecat建议,只需将基类型作为参数传递,使用is该参数:

procedure Add (Element : TDataType);        
Run Code Online (Sandbox Code Playgroud)

就像Rob在你上一个问题的评论中指出的那样:如果你只允许两种类型并且根据实际类型有条件,它就不是通用的.因此,泛型可能是错误的工具.

希望有所帮助.

  • @conciliator:即使你有10多种不同的类型,如果你想将它们放在10多个不同的列表中,泛型不是可行的方法,而且重载的方法更好(这个答案为+1).无论如何,如果你对Delphi相对较新,我强烈建议远离泛型,除非有一个非常令人信服的案例 - 至少在Delphi 2009中我们开发人员被视为对这个新的一个巨大的现场测试功能,你永远不会真正知道你是否有f*ed up或编译器是责任当事情不起作用. (2认同)