Создать объект в инструкции ‘with’ без использования переменной

#variables #delphi #with-statement #declare

#переменные #delphi #with-statement #объявить

Вопрос:

 var 
  UserName, NickName, UserID: string;
begin
  with TStringList.Create do
  begin
    CommaText := 'ali,veli,4950';
    UserName := x[0];  //what is x ? (x is Tstringlist.create)
    NickName := x[1];
    UserID := x[2];
  end;   
end;
  

Если я использую приведенный ниже код, это работает. Но я не хочу объявлять переменную. Могу ли я использовать его с любой переменной?

Как я могу использовать это в with инструкции?

 var 
  tsl: TStringList;
begin
  tsl := TStringlist.Create;
  with tsl do
  begin
    CommaText := 'ali,veli,4950';
    UserName := tsl[0]; 
    NickName := tsl[1];
    UserID := tsl[2];
  end;
end;
  

Комментарии:

1. Вам не нужно обращаться к самому списку, вы можете получить доступ к элементам через их свойство, то есть: строки. Имя пользователя:= strings[0]; псевдоним:= strings[1]; ….

2. Сделайте себе одолжение и прекратите использовать with . Я должен поддерживать базу кода, в которой первоначальные авторы считали это хорошей идеей. Это усложняет обслуживание и отладку, не экономя значительного времени. ПОЧЕМУ вы не хотите использовать переменную? Это сработает? На какую версию Delphi вы ориентируетесь? Если вы используете 10.3 (Rio) или более позднюю версию, вы можете использовать встроенные объявления: var ts := TStringList.Create; try ts.CommaText := '...'; finally ts.Free; end;

3. Вы не продвинетесь далеко, если ваша основная цель — избежать использования переменных. Вы не должны использовать with, за исключением очень редкого набора очень специфичных сценариев. Это не один из них.

Ответ №1:

Когда объект создается непосредственно в with инструкции, нет синтаксиса для ссылки на этот объект (если только он не предоставляет элемент, который ссылается на самого себя, что встречается очень редко), поэтому вы обычно должны использовать переменную, как это делает ваш нижний код.

Кроме того, оба кода приводят к утечке TStringList объекта, поскольку вы не вызываете Free() его, когда заканчиваете его использовать.

При этом, в этом конкретном примере [] оператор является просто сокращением для доступа к свойству по TStrings.Strings[] умолчанию, к которому вы можете получить доступ, не прибегая к переменной для созданного TStringList объекта, точно так же, как вы делаете со TStrings.CommaText свойством, например:

 var 
  UserName, NickName, UserID: string;
Begin
  with TStringList.Create do
  try
    CommaText := 'ali,veli,4950';
    UserName := Strings[0];
    NickName := Strings[1];
    UserID := Strings[2];
  finally
    Free;
  end;
end;