首页 > 解决方案 > 在 delphide 中使用动态字节数组时出现错误

问题描述

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

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

和我的德尔福代码:

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#代码

标签: delphi

解决方案


您忘记指定您收到的错误消息以及在哪一行(总是这样做!),但几乎可以肯定它是 E2008: Incompatible types at the propertyline。

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

对于数组属性,访问说明符必须列出方法而不是字段。读取说明符中的方法必须是一个函数,它以相同的顺序获取属性索引参数列表中列出的参数的数量和类型,并且其结果类型与属性的类型相同。write 说明符中的方法必须是一个过程,该过程采用属性索引参数列表中列出的参数的数量和类型,以相同的顺序,加上与属性相同类型的附加值或 const 参数。

我们举个例子:

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

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

相反,你必须做

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;

或者,很可能跳过该属性并将该字段设为公开:

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

最后,可以将字段私有但动态数组类型的公共属性:

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;

始终const开放数组参数上使用:

当您将数组作为开放数组值参数传递时,编译器会在例程的堆栈框架内创建该数组的本地副本。注意不要通过传递大数组来溢出堆栈。


最后,你的

fTransmittedBytes := transmittedBytes;

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

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

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


推荐阅读