2008-12-09 169 views
1

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

假设你有一个称为TStrings的类(为了解释起见使用Delphi),它至少有一个抽象方法和一个名为TStringList的后代类,它显然实现了抽象方法,但它没有引入任何你需要的东西尚未在祖先中实现,您将如何声明TStringList类型的函数变量?

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

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; 
+0

有人想添加一个语言标记,或者是有一个,我只是不知道它。 – UnkwnTech 2008-12-09 11:44:25

回答

1

它是一个TStringList,所以你也应该声明它为TStringList(第一个例子)。其他一切都可能会让你或其他人在后面读取代码时感到困惑。

0

我的投票是第二种形式 - 这个想法是TStrings定义了一个契约/接口,并且更好地为他们编写代码。

0

我想说,这取决于你是否期望如果TStringList可能会改变为其他实现TStrings的东西。如果你不希望它改变,可以使用TStringList并获得仅仅在TStringList中的特殊功能(猜测情况并非如此)。如果您希望它可能会更改,请将其声明为TStrings并坚持“安全”方法。

在这个特定的情况下,我会说没关系。地狱,你可能会改变变量声明,并且无论如何都不会改变。所以请选择你最喜欢的 - 这是一个偏好问题。

0

我同意Schnaader。

TStringList有更多的属性和方法TStrings(它是一个抽象类)。使用TStrings变量禁止使用这些成员使用您正在使用的演员。但是我认为这使事情变得更糟。

您可以在函数参数中使用TStrings。

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

或者作为一个属性。但是,如果局部变量和字段被标记为真实类型,则它们更具多功能性。

0

这取决于...

在Java中,我经常看见使用最高的抽象级别可用做声明的建议,虽然它一般适用于接口。

例如:

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


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

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

另一个优点:当一个方法需要一个Collection参数时,只要它只需要使用泛型方法,它就可以在更广泛的输入范围内工作。