代码之家  ›  专栏  ›  技术社区  ›  Gerhard Wessels

如何声明变量

  •  1
  • Gerhard Wessels  · 技术社区  · 17 年前

    我和一位同事一直在讨论如何在函数中声明变量。

    这里有两个例子。哪一种被认为是更好的做法?为什么?

    procedure AddElements;
    var
      aList: TStringList;
    begin
      aList := TStringList.Create;
      try
        aList.Add('Apple');
        aList.Add('Pear');
      finally
        aList.free;
      end;
    end;
    
    procedure AddElementsII;
    var
      aList: TStrings;
    begin
      aList := TStringList.Create;
      try
        aList.Add('Apple');
        aList.Add('Pear');
      finally
        aList.free;
      end;
    end;
    
    5 回复  |  直到 17 年前
        1
  •  1
  •   schnaader    17 年前

    它是一个TStringList,因此您还应该将其声明为TStringList(第一个示例)。其他一切都可能使您或稍后阅读代码的其他人感到困惑。

        2
  •  0
  •   Chris Kimpton    17 年前

    我的投票是第二种形式——其想法是TStrings定义了一个契约/接口,最好是为它们编写代码。

        3
  •  0
  •   Vilx-    17 年前

    我想说,这取决于您是否期望将TStringList更改为其他实现tstring的东西。如果您不希望它发生变化,那么使用TStringList并访问TStringList中单独存在的特殊功能(估计情况并非如此)。如果您预期它可能会更改,请将其声明为tstring并坚持使用“安全”方法。

        4
  •  0
  •   Toon Krijthe    17 年前

    TStringList比TStrings(一个抽象类)有更多的属性和方法。除非使用强制转换,否则使用TStrings变量禁止使用这些成员。但在我看来,这让事情变得更糟。

    可以在函数参数中使用tstring。

    procedure TMyClass.MyMethod(const AList: TStrings);
    begin
    end;
    

    或者作为一种财产。但是,如果局部变量和字段被标记为其真实类型,则它们的用途更广泛。

        5
  •  0
  •   PhiLho    17 年前

    这取决于。。。

    在Java中,我经常看到使用可用的最高抽象级别进行声明的建议,尽管它通常适用于接口。

    例如:

    Collection list = new ArrayList();
    [loop] list.add(someItem); [end loop]
    


    为什么?它允许通过最小化更改的影响来更改实现(在某些情况下是一个细节:某些实现更适合某些用途(队列、链表、堆栈…),因此它可能主要是一个速度/内存问题)。

    当然,如果使用特定于实现的方法,则必须在声明中更加具体。

    另一个优点是:当一个方法需要一个集合参数时,只要它只需要使用泛型方法,它就可以处理更广泛的输入范围。