4

我正在使用 Delphi 7。

这是我的基类。函数load_for_edit()应该返回一个字符串数组,听起来像它。问题并不特别在这里,而是更进一步。

    ...

type
    TStringArray = array of string;

    ...

    function load_for_edit(): TStringArray;

    ...

    numberOfFields: integer;

    ...

function TBaseForm.load_for_edit(): TStringArray;
var
    query: TADOQuery;
    i: integer;
begin
    query := TADOQuery.Create(self);
    query.Connection := DataModule1.ADOConnection;
    query.SQL.Add('CALL get_' + self.table_name + '_id(' + self.id + ')');
    query.Open;

    numberOfFields := query.Fields.Count;
    SetLength(result, query.Fields.Count);
    for i := 0 to query.Fields.Count - 1 do
        result[i] := query.Fields[i].Value.AsString;
end;

接下来是作为基类后代的类,它试图从基类的load_for_edit()函数接收一个数组。

    ...

type
    TStringArray = array of string;

    ...

procedure TPublisherEditForm.FormShow(Sender: TObject);
var
    rec: TStringArray;
begin
    inherited;
    SetLength(rec, self.numberOfFields);
    rec := load_for_edit();                 // Compilation stops here
end;

但是,应用程序不会编译。Delphi 吐出这个错误信息:

Incompatible types

因此,这意味着函数load_for_edit()返回的数据类型与变量rec的数据类型不同,但是,从它们各自的类型声明部分可以看出,它们的声明绝对相同。我不知道这里发生了什么以及该怎么做。请帮我想出一个解决方案。

4

1 回答 1

3

你有两个单独的声明TStringArray(每个单元一个),它们一样。(它们在两个单独的单元中的事实使它们不同。UnitA.TStringArray与不同UnitB.TStringArray,即使它们都被声明为type TStringArray = array of string;。)

您需要使用单一类型声明:

unit
  BaseFormUnit;

interface

uses
  ...
type
  TStringArray: array of string;

  TBaseForm = class(...)
    numberOfFields: Integer;
    function load_for_edit: TStringArray;
  end;

implementation

// Not sure here. It looks like you should use a try..finally to
// free the query after loading, but if you need to use it later
// to save the edits you should create it in the TBaseForm constructor
// and free it in the TBaseForm destructor instead, which means it
// should also be a field of the class declaration above.
function TBaseForm.load_for_edit(): TStringArray;
var
  query: TADOQuery;
  i: integer;
begin
  query := TADOQuery.Create(self);
  query.Connection := DataModule1.ADOConnection;
  query.SQL.Add('CALL get_' + self.table_name + '_id(' + self.id + ')');
  query.Open;

  numberOfFields := query.Fields.Count;
  SetLength(result, numberOfFields);
  for i := 0 to numberOfFields - 1 do
    Result[i] := query.Fields[i].Value.AsString;
end;
...
end.

现在您的后代类可以访问它:

unit
  PublisherEditFormUnit;

interface

uses
  ...  // Usual Forms, Windows, etc.
  BaseFormUnit;

type
  TPublisherEditForm = class(TBaseForm)
  ...
    procedure FormShow(Sender: TObject);
  end;

implementation

procedure TPublisherEditForm.FormShow(Sender: TObject);
var
  rec: TStringArray;
begin
  // No need to call SetLength - the base class does.
  rec := load_for_edit();                 // Compilation stops here
end;
...
end.
于 2013-04-13T01:03:04.570 回答