如何声明变量

发布于 2024-07-09 16:05:53 字数 598 浏览 11 评论 0原文

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

假设你有一个名为 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;

A colleague of mine and I have been discussing how to declare variables in a function.

Let's say you have a class called TStrings (using Delphi for the sake of explanation) that has at least one abstract method and a descendant class called TStringList which obviously implements the abstract method, but it introduces nothing else you need that is not already implemented in the ancestor, how would you declare a function variable of type TStringList?

Here are two examples. Which is considered better practice and why?

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;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

污味仙女 2024-07-16 16:05:53

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

It is a TStringList, so you should also declare it as TStringList (first example). Everything else could confuse you or others that read the code later.

幸福丶如此 2024-07-16 16:05:53

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

My vote is the second form - the idea being that TStrings defines a contract/interface and its better to code to them.

我恋#小黄人 2024-07-16 16:05:53

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

在这种具体情况下,我会说这并不重要。 天哪,你可能可以更改变量声明,但无论如何都不会改变。 因此,使用您最喜欢的任何一个 - 这是一个偏好问题。

I'd say that it depends on whether you expect if the TStringList might be changed to something else that implements TStrings or not. If you don't expect it to change, use TStringList and gain access to special features that are in TStringList alone (guess this is not the case). If you expect it might change declare it as TStrings and stick to the "safe" methods.

In this specific case I'd say it doesn't matter. Hell, you could probably change the variable declaration and nothing would change anyway. So use whichever you like best - it's a question of preference.

会发光的星星闪亮亮i 2024-07-16 16:05:53

我同意施纳德的观点。

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

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

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

或者作为财产。 但是,如果局部变量和字段被声明为真实类型,则它们的用途会更加广泛。

I agree with Schnaader.

TStringList has more properties and methods that TStrings (which is an abstract class). Using the TStrings variable prohibits the use of these members unles you are using casts. But that is making things worse in my opinion.

You can use TStrings in a function argument.

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

Or as a property. But local variables and fields are more versatile if they are decalared their real type.

穿透光 2024-07-16 16:05:53

这取决于...

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

例如:

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

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

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

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

It depends...

In Java, I often saw the recommendation of making declarations using the highest abstraction level that is usable, although it generally apply to interfaces.

For example:

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

etc.
Why? It allows to change implementation (a detail in some cases: some implementations are better suited to some usages (queue, linked list, stack...) so it might be mostly a speed/memory concern) by minimizing the impact of the change.

Of course, if you use methods specific to an implementation, you must be more specific in the declaration.

Another advantage: when a method expect a Collection parameter, it can work on a broader range of input as long as it needs to use only generic methods.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文