2008-12-09 2 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 запрещает использование этих членов unles, которые вы используете при произнесении. Но, по моему мнению, это ухудшает ситуацию.

Вы можете использовать TStrings в аргументе функции.

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

Или как собственность. Но локальные переменные и поля более универсальны, если они декальцируют их реальный тип.

0

Это зависит ...

В Java, я часто видел рекомендацию делать заявление, используя высокий уровень абстракции, который можно использовать, хотя он обычно применяется к интерфейсам.

Например:

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

и т.д.
Почему? Он позволяет изменять реализацию (в некоторых случаях это детализация: некоторые реализации лучше подходят для некоторых способов использования (очередь, связанный список, стек ...), поэтому это может быть главным образом проблема скорости/памяти), минимизируя влияние изменения.

Конечно, если вы используете методы, специфичные для реализации, вы должны быть более конкретными в декларации.

Другое преимущество: когда метод ожидает параметр Collection, он может работать с более широким диапазоном ввода, если ему нужно использовать только общие методы.