在 delphide 中使用动态字节数组时出现错误

I get an error when using the dynamic byte array in delphide

我正在和 delphi 一起做一个项目。该项目有c#代码。我在项目中使用字节数组。但是我得到一个错误。 C#代码:

public class DataTransmitEventArgs : EventArgs
    {
        public DataTransmitEventArgs(byte[] transmittedBytes)
        {
            fTransmittedBytes = transmittedBytes;
        }
        byte[] fTransmittedBytes;
        public byte[] TransmittedBytes
        {
            get { return fTransmittedBytes; }
        }
    }

和我的 Delphi 代码:

DataTransmitEventArgs = class

 public
 fTransmittedBytes: array of byte;
 constructor  Create(transmittedBytes: array of byte);overload;
 property TransmittedBytes[index: byte]:Byte read fTransmittedBytes;
 end;

  constructor DataTransmitEventArgs.Create(transmittedBytes: array of byte);
     begin
             fTransmittedBytes := transmittedBytes;
     end;

如何使用 delphi

编写这些 C# 代码

您忘记指定收到的错误消息以及在哪一行(总是这样做!),但几乎可以肯定是 E2008:property 行不兼容的类型。

根据应该始终是您的第一个信息来源的文档,array property 不能将字段(如 fTransmittedBytes)作为其访问说明符(读或写)。相反,它们必须是方法:

For array properties, access specifiers must list methods rather than fields. The method in a read specifier must be a function that takes the number and type of parameters listed in the property's index parameter list, in the same order, and whose result type is identical to the property's type. The method in a write specifier must be a procedure that takes the number and type of parameters listed in the property's index parameter list, in the same order, plus an additional value or const parameter of the same type as the property.

举个例子:

type
  TTest = class
  private
    FData: array of Byte;
  public
    property Data[Index: Integer]: Byte read FData write FData;
  end;

违反此要求并在 read 处发出 E2008(如果修复 readwrite)。

相反,您必须这样做

type
  TTest = class
  private
    FData: array of Byte;
    function GetData(Index: Integer): Byte;
    procedure SetData(Index: Integer; const Value: Byte);
  public
    property Data[Index: Integer]: Byte read GetData write SetData;
  end;

{ TTest }

function TTest.GetData(Index: Integer): Byte;
begin
  Result := FData[Index];
end;

procedure TTest.SetData(Index: Integer; const Value: Byte);
begin
  FData[Index] := Value;
end;

如果您想要额外的安全,请执行 (uses Math)

function TTest.GetData(Index: Integer): Byte;
begin
  if InRange(Index, Low(FData), High(FData)) then
    Result := FData[Index]
  else
    raise Exception.CreateFmt('Index out of bounds: %d', [Index]);
end;

procedure TTest.SetData(Index: Integer; const Value: Byte);
begin
  if InRange(Index, Low(FData), High(FData)) then
    FData[Index] := Value
  else
    raise Exception.CreateFmt('Index out of bounds: %d', [Index]);
end;

或者,也可以跳过 属性 并将字段设置为 public:

type
  TTest = class
  public
    Data: array of Byte;
  end;

最后,可以将字段设为私有,但 dynamic array 类型的 public 属性:

type
  TTest = class
  private
    FData: TArray<Byte>;
  public
    property Data: TArray<Byte> read FData write FData;
  end;

如果您使用的是 Delphi 的前泛型版本,TArray<Byte> 显然不可用,因此您必须定义自己的类型:type ByteArray = array of Byte.


此外,您还有

constructor  Create(transmittedBytes: array of byte);overload;

应该是

constructor Create(const ATransmittedBytes: array of Byte); overload;

始终在 open array parameters 上使用 const:

When you pass an array as an open array value parameter, the compiler creates a local copy of the array within the routine's stack frame. Be careful not to overflow the stack by passing large arrays.


最后,你的

fTransmittedBytes := transmittedBytes;

也不会编译,因为您不能简单地将 开放数组 分配给 dynamic array.

相反,您可以将参数更改为动态数组类型:

constructor Create(const ATransmittedBytes: TArray<Byte>); overload;

您可能还想 Copy 数组:

FTransmittedBytes := Copy(ATransmittedBytes);

或者,您可以使用 SetLength 和一个简单的 for 循环来复制数组:

SetLength(FTransmittedBytes, Length(ATransmittedBytes));
for i := 0 to High(ATransmittedBytes) do
  FTransmittedBytes[i] := ATransmittedBytes[i];

开数组的下界总是0.