【问题标题】:What's the difference between casting using (Object as TClass) and TClass(Object)使用 (Object as TClass) 和 TClass(Object) 进行强制转换有什么区别
【发布时间】:2011-01-27 19:58:57
【问题描述】:

遇到MyObj.classnameis(TMyClass.classname) 为真且TMyClass(MyObj) 有效但(MyObj as TMyclass).doSomething 引发转换错误的问题。

我真的不希望对那些垃圾有任何帮助,但如果你想把它放在 cmets 中,那就太好了。我只是想知道Obj as ClassClass(Obj)有什么区别。

【问题讨论】:

  • 那是相当多的标签。我认为'delphi'就足够了。
  • 感谢您指出我刚才指出的问题
  • 您使用 DLL 吗? DLL 混淆了类标识。
  • 是的,很确定这是一个 DLL 问题。
  • 是的,这可能是问题的一部分。 DLL 包含它们自己的声明对象的单元的副本。类型检查通过比较基本上是 VMT 指针的类引用来工作。如果 EXE 和 DLL 都有自己的 VMT 副本,则检查将失败。这就提出了一个问题,为什么要将对象传入和传出 DLL?

标签: delphi casting typecast-operator


【解决方案1】:

一个 as-cast 检查实际的对象类型以确保 cast 有效,如果不是则引发异常。 “硬转换”(TMyClass(MyObj) 风格)不会检查,它只是告诉编译器假设转换是有效的。

如果您遇到 ClassNameIs 返回 true 但 as-cast 失败的情况,这意味着您在两个具有相同名称的不同单元中有两个不同的类,并且 as-cast 试图转换为错误的类.这也意味着您的硬转换转换为错误的,这可能会导致内存损坏。

运行完整的项目搜索“TMyclass=”以查看您的多个声明在哪里,然后重命名其中一个类或使用完整定义(obj 为 MyUnit.TMyClass),以便编译器知道您是哪个类试图投射到。

【讨论】:

  • 硬演员(没有 as)在评估/修改和观看屏幕上效果更好。
【解决方案2】:

梅森帖子的补充: 除了搜索您的代码之外,您还可以在给您带来问题的位置调用类似这样的方法。

function GetClassInheritance(Obj : TObject) : string;
var ClassRef : TClass;
begin
  Result := '';
  ClassRef := obj.ClassType;
  Result := ClassRef.ClassName;
  ClassRef := ClassRef.ClassParent;
  while assigned(ClassRef) do
  begin
    Result    := ClassRef.ClassName + '.' + Result;
    ClassRef  := ClassRef.ClassParent;
  end;

  Result := '(' + obj.ClassType.UnitName + ')' + Result
end;

这将返回一个格式为 (UnitName)TObject.TPersistent.TComponent.... 的字符串。 我不记得在旧版本的 delphi 中看到“ClassType.UnitName”,因此该部分可能无法与它们一起使用,但其余部分应该。

【讨论】:

    猜你喜欢
    • 2019-12-06
    • 1970-01-01
    • 1970-01-01
    • 2011-08-12
    • 2016-02-09
    • 2013-05-31
    • 2018-06-20
    • 2013-04-11
    相关资源
    最近更新 更多