代码之家  ›  专栏  ›  技术社区  ›  M Schenkel

是否有编译时标志来防止不使用“对象”从StringList访问对象

  •  0
  • M Schenkel  · 技术社区  · 15 年前

    我不知道我犯了多少次错误:

    for  i := 0 to MyList.count-1 do begin
      myobject := TMyObject(MyList[i])
      .......
    end;
    

    什么时候应该这样:

    for  i := 0 to MyList.count-1 do begin
      myobject := TMyObject(MyList.objects[i])
      .......
    end;
    

    注意 物体 在第二段代码中。

    错误的代码片段将运行,并且在我尝试使用MyObject时明显会引发访问冲突。但并不总是很明显我做错了什么。

    有没有编译器选项可以防止这种情况发生?

    3 回复  |  直到 15 年前
        1
  •  7
  •   Daniel Maurić    15 年前

    Delphi有两种类型化的方法,使用 TObject(var) 以及使用 As 操作员。 总是使用 AS 除非你百分之百确定。 在你的具体例子中

    (MyList[i]) as TMyObject 不编译 在哪里

    (MyList.objects[i]) as TMyObject 做。

        2
  •  5
  •   Rob Kennedy    15 年前

    不。当您键入cast时,编译器假定您知道自己在做什么。它将允许几乎所有类型转换,其中两种类型的大小相同,但值得注意的是整数类型和浮点类型之间的转换除外。

    对于这个特殊的例子,试着让自己养成使用 as 而不是操作员。当您忘记使用 Objects 财产:

    myobject := MyList[i] as TMyObject; // compiler error
    myobject := MyList.Objects[i] as TMyObject; // OK
    
        3
  •  3
  •   Kenneth Cochran    15 年前

    看起来您正在使用tstringlist保存字符串/对象对。如果您使用的是Delphi2009或更高版本,则另一个建议是用类似于这样的通用TDictionary替换TStringList:

    uses
      Generics.Collections;
    ...
    MyDictionary: TDictionary<String, TMyObject>;
    ...
    for  MyObject in MyDictionary.Values do
    begin
      ...
    end;
    

    那么整个操作是类型安全的,您根本不需要强制转换。

    注: 不能在for..in循环内重新分配迭代变量(但可以调用其方法并更改其属性的值)。