【问题标题】:Not able to cast TList<T> item that is an interface无法转换作为接口的 TList<T> 项
【发布时间】:2015-10-01 23:52:18
【问题描述】:

为什么这段代码不能从需要特定接口的泛型列表中转换为 IDeletableNode。

无论我如何转换,此代码示例都无法执行 IDeletableNode.Delete 过程。

    unit DeletableGenericsTest;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, xmldom, XMLDoc, XMLIntf, Generics.Collections;

type

  IDeletableNode = interface(IXMLNode)
    ['{04D7A0C0-8E87-412B-BC55-230C7080D410}']
    procedure Delete;
  end;

  INodeOfData = interface(IDeletableNode)
     ['{368917D8-402F-4BA2-8BC5-B0DB51B1BAE9}']
     function Get_MyKey : string;
     property MyKey : string read Get_MyKey;
  end;

  TDeletableList<T: IDeletableNode> = class(TList<T>)
     procedure DeleteAll;
  end;

  TNodeOfData = class(TXMLNode, INodeOfData)
  protected
     function Get_MyKey: string;
  public
     procedure Delete;
  end;

  TForm1 = class(TForm)
  private
    fListOfNodes : TDeletableList<TNodeOfData>;
  public
    { Public declarations }
  end;


var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TDeletableList<T> }

procedure TDeletableList<T>.DeleteAll;
var
index : Integer;
begin
   for index := Self.Count - 1 downto 0 do
       Self[index].Delete;
end;

{ TNodeOfData }

procedure TNodeOfData.Delete;
begin
   // delete some stuff;
end;

function TNodeOfData.Get_MyKey: string;
begin
   result := '123ABC';
end;

end.

这里有什么我遗漏的东西还是正确的?

【问题讨论】:

  • 失败的代码在哪里?你说的类型转换在哪里不起作用?
  • 使用您显示的代码,Self[index].Delete 在 XE2 中尝试时对我来说效果很好(我确实定义了自己的 IXMLNodeTXMLNode 类型。您使用的是Xml.XmlIntfXml.XmlDoc 单位?)。正如预期的那样,TNodeOfData.Delete 被调用。 Error Insight 说Delete 未声明,但代码编译并运行。如果您遇到实际的编译器错误,请提供完整的MCVE 以重现错误。
  • 感谢 Jens 的参考,但这个问题似乎与声明多个泛型类型时使用逗号代替分号的代码有关。
  • TNodeOfData 没有实现IDeletableNode。尝试将其声明为TNodeOfData = class(TXMLNode, INodeOfData, IDeletableNode)
  • 这很容易通过将接口定义推送到单独的单元中来解决,这些单元可以被所有实现和使用它们的单元使用。

标签: delphi generics interface delphi-xe7


【解决方案1】:

您问题中的代码失败并出现此错误:

[dcc32 错误] E2514 类型参数“T”必须支持接口“IDeletableNode”

在这一行:

fListOfNodes : TDeletableList<TNodeOfData>;

编译器非常清楚地告诉您,TNodeOfData 必须实现 IDeletableNode,但它没有。这是因为对泛型参数的限制:

TDeletableList<T: IDeletableNode> = class(TList<T>)

所以改变

TNodeOfData = class(TXMLNode, INodeOfData)

TNodeOfData = class(TXMLNode, IDeletableNode, INodeOfData)

你的代码将被编译。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-25
    • 2016-02-13
    • 2022-11-29
    • 1970-01-01
    • 1970-01-01
    • 2019-02-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多