How to declare variables

My colleague and I discussed how to declare variables in a function.

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

Here are two examples. What is considered best 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;

      

+1


source to share


5 answers


This is a TStringList, so you must also declare it as TStringList (first example). Anything else may confuse you or others who read the code later.



+1


source


My vote is the second form - the idea is that TStrings define a contract / interface and better code it.



0


source


I would say it depends on whether you expect the TStringList to be changed to another one that implements TStrings or not. If you don't expect it to change, use a TStringList and get access to special functions that only TStringList has (guess not). If you expect this to change, declare it as TStrings and stick to "safe" methods.

In this particular case, I would say it doesn't matter. Heck, you can probably change the variable declaration and nothing will change. So use whichever you like best - it's a matter of preference.

0


source


I agree with Schnaader.

TStringList has more properties and methods that TStrings (which is an abstract class). Using the TStrings variable disallows the use of those unles members that you use when pronouncing. But it makes things worse in my opinion.

You can use TStrings in the function argument.

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

      

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

0


source


It depends...

In Java, I have often seen a recommendation to make declarations using the highest abstraction level that can be used, although it usually applies to interfaces.

For example:

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

      

etc ..
Why? It allows you to change the implementation (in some cases it's granularity: some implementations are better suited for some use cases (queue, linked list, stack ...), so it can be mostly a speed / memory issue) while minimizing the impact of the change.

Of course, if you are using implementation-specific methods, you should be more specific in your declaration.

Another benefit is that when a method expects a Collection parameter, it can handle a wider range of input if it only needs to use generic methods.

0


source







All Articles