Нетипизированные / не типизированные параметры в Delphi - PullRequest
11 голосов
/ 18 декабря 2009

Какого типа параметры без типа, как в классе TStringStream:

function Read(var Buffer; Count: Longint): Longint; override;

Каков тип параметра Buffer (это тип Pointer?).

Ответы [ 4 ]

21 голосов
/ 18 декабря 2009

Я написал статью на эту тему несколько лет назад:

Что такое нетипизированный параметр?

Нетипизированные параметры используются в нескольких ситуациях; TStream.Read метод, о котором вы спрашиваете, наиболее близко совпадает с Move процедурой, о которой я писал. Вот выдержка:

procedure Move(const Source; var Dest; Count: Integer);

Процедура Move копирует данные из произвольной переменной в любую другую переменную. Необходимо принять источники и направления все типы, что означает, что он не может требовать какого-либо одного типа. Процедура не изменяет значение переменной, переданной для Source, так что объявление параметра использует const вместо var, который является более распространенный модификатор для нетипизированных параметров.

В случае TStream.Read источником является содержимое потока, поэтому вы не передаете его в качестве параметра, а местом назначения является параметр Buffer, показанный в вопросе. Вы можете передать любой тип переменной для этого параметра, но это означает, что вы должны быть осторожны. Это ваша задача, а не компилятор, чтобы гарантировать, что содержимое потока действительно является допустимым значением для типа параметра, который вы предоставляете.

Прочитайте остальную часть моей статьи, чтобы узнать больше о ситуациях, когда Delphi использует нетипизированные параметры.

3 голосов
/ 18 декабря 2009

Ознакомьтесь с справкой Delphi по "нетипизированным параметрам"

Вы можете передать любой тип, но вы должны привести его к реализации. Справка говорит, что вы не можете передать ей числовую или нетипизированную числовую константу. Таким образом, в основном вы должны знать, какой тип ожидать, и компилятор не может вам помочь, поэтому у вас должна быть веская причина, чтобы сделать это таким образом. Я полагаю, что он может быть полезен, если вам нужен метод для обработки несовместимых типов, но с другой стороны, вы можете написать несколько перегруженных версий для каждого ожидаемого типа, я бы предложил это как лучшее решение.

0 голосов
/ 23 августа 2010

Возможно, что удивительно, допустимо передавать разыменованный указатель как нетипизированный параметр. И сам указатель даже не должен иметь тип.

procedure SomeMethod(var aParameter);
  ∶

procedure CallSomeMethod(aIsInteger : Boolean);
type
  buffer    : Pointer;
  intValue  : Integer;
  realValue : Single;
begin
  if aIsInteger then
  begin
    buffer := @intValue;
  end
  else
  begin
    buffer := @realValue;
  end;
  SomeMethod(buffer^);

Конечно, возможно, было бы проще, если бы параметр SomeMethod () был указателем, но это может быть не под вашим контролем.

0 голосов
/ 18 декабря 2009

var в списке параметров является синтаксисом Delphi для вызова по ссылке . Это может быть напечатано как, например. параметр AllowChange в обработчике OnChanging Listview:

procedure TSomeForm.LVOnChanging(Sender: TObject; ...; var AllowChange: Boolean);
begin
  if SomeProblemOccurred then
    AllowChange := False;
end;

или нетипизированный , как в вашем примере.

...