为什么我收到了Delphi不兼容的类型(数组和动态数组)的错误? [英] Why am I receiving an error about Delphi incompatible types (array and dynamic array)?
问题描述
(修改:这是从是对象在Windows针对性的Delphi应用程序引用计数以下,并如果是这样,其目的是什么?和动态数组和德尔福内存管理)。
我有两个类( TGenericHoldingSummary
, TGenericHoldingResultSet
)和一个记录( TGenericHoldingResult
)。
-
TGenericHoldingSummary
包含一个TGenericHoldingResultSet
,它被设置为无$ C如果需要时$ C>并从数据库中延迟加载。
- 的
TGenericHoldingResultSet
包含TGenericHoldingResult
记录的动态数组。
在下面的,错误是在 TGenericHoldingResultSet
构造函数赋值。
TGenericHoldingResult =记录
code:整数;
级别:字符串;
味精:字符串;
结束;TGenericHoldingResultSet =类(TObject的)
上市
// 生命周期
构造函数创建(父:TGenericHoldingSummary; resArr:TGenericHoldingResult数组);
析构函数销毁;
//访问器
功能RESULTCOUNT个():整数;
函数结果(I:整数):TGenericHoldingResult;
私人的
//变量
总结:TGenericHoldingSummary;
resultArray:TGenericHoldingResult阵列;
结束;TGenericHoldingSummary =类(TObject的)
上市
//注意摘要对象拥有的结果,并释放
//它的析构函数的内存。
功能的getResultSet:TGenericHoldingResultSet;
私人的
//成员变量
的resultSet:TGenericHoldingResultSet;
结束;//注意摘要对象拥有的结果,并释放
//它的析构函数的内存。
功能TGenericHoldingSummary.getResultSet():TGenericHoldingResultSet;
VAR
SQL:字符串;
我:整数;
resultArray:TGenericHoldingResult阵列;
开始
如果=的resultSet则为零
开始
//获取通过SQL结果。
SetLength函数(resultArray,holding.clientDataSet.RecordCount); 对于i:= 0 holding.clientDataSet.RecordCount - 1做
开始
resultArray [I] code:= holding.clientDataSet.FieldByName('code')AsInteger;
resultArray [I] .LEVEL:= holding.clientDataSet.FieldByName('级别')AsString。
resultArray [I]。味精:= holding.clientDataSet.FieldByName(信息)AsString。
结束; 的resultSet:= TGenericHoldingResultSet.Create(个体经营,resultArray);
结束; 结果:=的resultSet;
结束;// 生命周期
构造TGenericHoldingResultSet.Create(父:TGenericHoldingSummary; resArr:TGenericHoldingResult数组);
开始
总结:=父母;
//下面的*应*工作,不应该吗?
//例如,看到动态数组在Delphi的引用计数
//所有平台上,这应该是简单的增加引用计数。
resultArray:= resArr;
结束;
该错误是如下:
[DCC错误] GenericHolding.pas(302):E2010不兼容的类型:动态数组和数组
您不能指定一个开放数组动态数组。请参见 开放数组参数
。
注:开放数组参数的语法类似于动态数组类型,但他们并不意味着同样的事情。在previous例子创建了一个函数,有字符元素,包括(但不限于)动态数组任何数组。要声明参数必须是动态数组,你需要指定一个类型标识符:
块引用>键入TDynamicCharArray =阵列字符的;
功能查找(常量答:TDynamicCharArray):整数;用例
开放式阵列
和动态数组的区别的一个很好的总结可以在这里找到:的打开数组参数
。如果您有支持泛型一个Delphi版本,它可以声明构造函数头:
构造TGenericHoldingResultSet.Create(父:TGenericHoldingSummary;
常量resArr:在tarray< TGenericHoldingResult>);和您的
resultArray
为在tarray< TGenericHoldingResult>
。这将避免在申报阵列的特定类型。
正如大卫指出,开放数组有一个好处,因为他们有更广阔的使用情况,并应使用时可能的。
(EDIT: This is following on from Are objects reference counted in Windows-targeted Delphi applications, and if so, what is its purpose? and Dynamic arrays and memory management in Delphi).
I have two classes (
TGenericHoldingSummary
,TGenericHoldingResultSet
) and one record (TGenericHoldingResult
).
TGenericHoldingSummary
contains a singleTGenericHoldingResultSet
, which is set tonil
and lazy-loaded from the database if and when required.- The
TGenericHoldingResultSet
contains a dynamic array ofTGenericHoldingResult
records.In the below, the error is at the assignment in the
TGenericHoldingResultSet
constructor.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;
The error is below:
[DCC Error] GenericHolding.pas(302): E2010 Incompatible types: 'Dynamic array' and 'Array'
解决方案You cannot assign an open array to a dynamic array. See
Open Array Parameters
.Note: The syntax of open array parameters resembles that of dynamic array types, but they do not mean the same thing. The previous example creates a function that takes any array of Char elements, including (but not limited to) dynamic arrays. To declare parameters that must be dynamic arrays, you need to specify a type identifier:
type TDynamicCharArray = array of Char; function Find(const A: TDynamicCharArray): Integer;
A good summary of the use case of
open arrays
and the difference with a dynamic array can be found here:Open array parameters
.
If you have a Delphi version that supports generics, it is possible to declare the constructor header:
constructor TGenericHoldingResultSet.Create(parent : TGenericHoldingSummary; const resArr : TArray<TGenericHoldingResult>);
and your
resultArray
asTArray<TGenericHoldingResult>
.This will avoid having to declare a specific type for the array.
As noted by David, open arrays have a benefit since they have a broader use case, and should be used when possible.
这篇关于为什么我收到了Delphi不兼容的类型(数组和动态数组)的错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!