2014-03-03 47 views
4

編輯:這是來自Are objects reference counted in Windows-targeted Delphi applications, and if so, what is its purpose?Dynamic arrays and memory management in Delphi)。爲什麼我收到有關Delphi不兼容類型(數組和動態數組)的錯誤?

我有兩個類(TGenericHoldingSummaryTGenericHoldingResultSet)和一個記錄(TGenericHoldingResult)。

  • TGenericHoldingSummary包含單個TGenericHoldingResultSet,其被設置爲nil和如果需要時從數據庫延遲加載。
  • TGenericHoldingResultSet包含TGenericHoldingResult記錄的動態數組。

在下面,錯誤是在TGenericHoldingResultSet構造函數賦值。

TGenericHoldingResult = record 
    code : Integer; 
    level : String; 
    msg : String; 
end; 

TGenericHoldingResultSet = class(TObject) 
    public 
    // Lifecycle 
    constructor Create(parent : TGenericHoldingSummary; resArr : Array of TGenericHoldingResult); 
    destructor Destroy; 
    // Accessors 
    function ResultCount() : Integer; 
    function Result(i : Integer) : TGenericHoldingResult; 
    private 
    // Variables 
    summary : TGenericHoldingSummary; 
    resultArray : Array of TGenericHoldingResult; 
end; 

TGenericHoldingSummary = class(TObject) 
public 
    // Note that the summary object 'owns' the results, and deallocates 
    // its memory in the destructor. 
    function getResultSet: TGenericHoldingResultSet; 
private 
    // Member variables 
    resultSet: TGenericHoldingResultSet; 
end; 

// Note that the summary object 'owns' the results, and deallocates 
// its memory in the destructor. 
function TGenericHoldingSummary.getResultSet() : TGenericHoldingResultSet; 
var 
    sql : String; 
    i : Integer; 
    resultArray : Array of TGenericHoldingResult; 
begin 
    if resultSet = nil then 
    begin 
    // Get results via SQL. 
    SetLength(resultArray, holding.clientDataSet.RecordCount); 

    for i := 0 to holding.clientDataSet.RecordCount - 1 do 
    begin 
     resultArray[i].code := holding.clientDataSet.FieldByName('code').AsInteger; 
     resultArray[i].level := holding.clientDataSet.FieldByName('level').AsString; 
     resultArray[i].msg := holding.clientDataSet.FieldByName('message').AsString; 
    end; 

    resultSet := TGenericHoldingResultSet.Create(self, resultArray); 
    end; 

    result := resultSet; 
end; 

// Lifecycle 
constructor TGenericHoldingResultSet.Create(parent : TGenericHoldingSummary; resArr : Array of TGenericHoldingResult); 
begin 
    summary := parent; 
    // The following *should* work, shouldn't it? 
    // E.g., seeing as dynamic arrays a reference counted in Delphi for 
    // all platforms, this should simply increment the reference count. 
    resultArray := resArr; 
end; 

的誤差小於:

[DCC Error] GenericHolding.pas(302): E2010 Incompatible types: 'Dynamic array' and 'Array' 

回答

5

您不能分配一個開放數組動態數組。見Open Array Parameters

注意:開放數組參數的語法類似於動態數組類型的語法,但它們並不意味着同樣的事情。前面的示例創建了一個接受任何Char元素數組的函數,包括(但不限於)動態數組。要聲明參數必須是動態數組,你需要指定一個類型標識符:

type TDynamicCharArray = array of Char; 
function Find(const A: TDynamicCharArray): Integer; 

open arrays的使用情況,並與一個動態數組的區別的一個很好的總結可以在這裏找到:Open array parameters


如果您有支持泛型一個Delphi版本,它可以聲明構造函數頭:

constructor TGenericHoldingResultSet.Create(parent : TGenericHoldingSummary; 
    const resArr : TArray<TGenericHoldingResult>); 

和你resultArrayTArray<TGenericHoldingResult>

這將避免必須爲數組聲明特定類型。

正如David指出的那樣,開放數組有一個好處,因爲它們有更廣泛的用例,應儘可能使用。

+0

這很有幫助,但現在我收到另一個錯誤。我改變了添加類型'TGenericHoldingResultDynamicArray = TGenericHoldingResult;數組'並且改變了參數,但是現在分配線'[DCC錯誤] GenericHolding.pas(261):E2010不兼容的類型:'TGenericHoldingResultDynamicArray'和'動態數組'。 – magnus

+0

resultArray也必須聲明爲'TGenericHoldingResultDynamicArray'。 –

+0

+1爲您的答案。 – magnus

相關問題