gpt4 book ai didi

delphi - 类型转换 TList to TList

转载 作者:行者123 更新时间:2023-12-03 18:41:49 27 4
gpt4 key购买 nike

我有一个 TList<TForm> 类型的列表.我需要将其转换为 TList<TObject>像这样:

procedure mainForm.testCast;
var
listT: TList<TForm>;
listW: TList<TObject>;
obj: TObject;
begin
listT := TList<TForm>.create;
listT.add(form1);
listT.add(form2);

listW := TList<TObject>(listT); // Casting is OK

// This works, but is this fine?
for obj in listW do
memo1.lines.add(obj.className);

end;

该示例按预期工作,但是可以在通用列表之间进行这样的转换吗?这会导致一些数据结构损坏等吗?
我仅将它用于循环( DoGetEnumerator )目的和一些字符串检查,即我不会添加/删除项目。

真正的功能稍微复杂一点。它引用 listTTValue 中使用 RTTI .
主要目标不是链接 FMX.Forms在我单位。

更新:
Why are TGeneric<Base> and TGeneric<Descendant> incompatible types?

最佳答案

好吧,你的代码会起作用,但在我看来它有点可疑。简单地说,类型转换是不合法的,因为

TList<TForm>.InheritsFrom(TList<TObject>)

是假的。所以一个 TList<TForm>对象不是 TList<TObject> .如果是这样,那么 Actor 就不需要了。

之所以如此,是因为 Delphi 的泛型类型是不变的。更多详情可在这找到:
Why is a class implementing an interface not compatible with the interface type when used in generics?

如果你很难理解为什么设计者让泛型类型保持不变,请考虑一下写 listW.Add(TObject.Create) 的效果。在你的代码中。想想它对 TList<TForm> 类型的真正底层对象意味着什么.

所以语言对你没有任何 promise 。您正在冒险超出其保证范围。碰巧这两种不相关类型的实现足够兼容,可以让您的代码正常工作。但这实际上只是实现的一个意外。

既然您已经在使用 RTTI,那么我建议您使用 RTTI 遍历列表。您可以调用 GetEnumerator等等使用RTTI。这样,您将调用对象的实际方法。

关于delphi - 类型转换 TList<T :class> to TList<W:class>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21677081/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com