Wenn Sie möchten, können Sie [][]
verwenden, um Elemente zuzugreifen. Wenn Ihr Typ ein Array ist (zweidimensionale oder gezackte Dynamik), wird diese Methode des Zugriffs auf die Elemente in die Sprache übernommen. Für einen benutzerdefinierten Typ müssen Sie ihn implementieren.
Es gibt keine Möglichkeit, [][]
in einem einzigen Schritt in einem benutzerdefinierten Typ zu implementieren. Was Sie tun müssen, ist den Prozess in zwei separate Teile zu brechen. Der erste Teil besteht darin, []
zu implementieren, um eine Zeile Ihrer Matrix zurückzugeben. Implementieren Sie dann []
in dieser Zeile, um ein Element zurückzugeben. Hier ein Beispiel:
type
TMatrix<T> = class
public
type
TRow = record
private
FMatrix: TMatrix<T>;
FRowIndex: Integer;
function GetItem(ColIndex: Integer): T; inline;
procedure SetItem(ColIndex: Integer; const Value: T); inline;
public
property Items[ColIndex: Integer]: T read GetItem write SetItem; default;
end;
private
FData: TArray<TArray<T>>;
function GetRow(RowIndex: Integer): TRow; inline;
public
constructor Create(RowCount, ColCount: Integer);
property Rows[RowIndex: Integer]: TRow read GetRow; default;
end;
{ TMatrix<T>.TRow }
function TMatrix<T>.TRow.GetItem(ColIndex: Integer): T;
begin
Result := FMatrix.FData[FRowIndex, ColIndex];
end;
procedure TMatrix<T>.TRow.SetItem(ColIndex: Integer; const Value: T);
begin
FMatrix.FData[FRowIndex, ColIndex] := Value;
end;
{ TMatrix<T> }
constructor TMatrix<T>.Create(RowCount, ColCount: Integer);
begin
inherited Create;
SetLength(FData, RowCount, ColCount);
end;
function TMatrix<T>.GetRow(RowIndex: Integer): TRow;
begin
Result.FMatrix := Self;
Result.FRowIndex := RowIndex;
end;
jedoch gezeigt hat, dass dies möglich ist, würde ich vorschlagen, dass mehr idiomatische ist ein array property mit zwei Indizes zu verwenden. Das würde bedeuten, dass Sie auf die Matrix mit M[Row,Col]
eher als M[Row][Col]
zugreifen würden. Dieses spezielle Idiom (M[Row,Col]
) ist nicht in allen Sprachen zu finden, so dass Sie es vielleicht nicht kennen. dass die Unterstützung könnte wie folgt aussehen:
type
TMatrix<T> = class
public
type
TRow = record
private
FMatrix: TMatrix<T>;
FRowIndex: Integer;
function GetItem(ColIndex: Integer): T; inline;
procedure SetItem(ColIndex: Integer; const Value: T); inline;
public
property Items[ColIndex: Integer]: T read GetItem write SetItem; default;
end;
private
FData: TArray<TArray<T>>;
function GetRow(RowIndex: Integer): TRow; inline;
function GetItem(RowIndex, ColIndex: Integer): T; inline;
procedure SetItem(RowIndex, ColIndex: Integer; const Value: T); inline;
public
constructor Create(RowCount, ColCount: Integer);
property Rows[RowIndex: Integer]: TRow read GetRow;
property Items[RowIndex, ColIndex: Integer]: T read GetItem write SetItem; default;
end;
{ TMatrix<T>.TRow }
function TMatrix<T>.TRow.GetItem(ColIndex: Integer): T;
begin
Result := FMatrix.FData[FRowIndex, ColIndex];
end;
procedure TMatrix<T>.TRow.SetItem(ColIndex: Integer; const Value: T);
begin
FMatrix.FData[FRowIndex, ColIndex] := Value;
end;
{ TMatrix<T> }
constructor TMatrix<T>.Create(RowCount, ColCount: Integer);
begin
inherited Create;
SetLength(FData, RowCount, ColCount);
end;
function TMatrix<T>.GetRow(RowIndex: Integer): TRow;
begin
Result.FMatrix := Self;
Result.FRowIndex := RowIndex;
end;
function TMatrix<T>.GetItem(RowIndex, ColIndex: Integer): T;
begin
Result := FData[RowIndex, ColIndex];
end;
procedure TMatrix<T>.SetItem(RowIndex, ColIndex: Integer; const Value: T);
begin
FData[RowIndex, ColIndex] := Value;
end;
Beachten Sie, dass in dieser Version, die wir gewählt haben, um Items
die Standardeigenschaft zu machen sein. Wenn Sie auf eine Zeile zugreifen möchten, müssen Sie die Rows
-Eigenschaft explizit benennen: M.Rows[RowIndex]
.
Ah! Danke, ich bekomme immer noch das Gefühl dieser Sprache und es sind kleine Fragen wie diese, die mich wirklich stolpern lassen. – Zulukas