Delphi中的变体记录

7

我只是想学习变体记录。有人能解释一下怎么检查记录的形状,比如矩形/三角形等等,或者有没有可用的实现好的示例? 我已经查看了这里的变体记录,但没有实现。

type
    TShapeList = (Rectangle, Triangle, Circle, Ellipse, Other);
    TFigure = record
    case TShapeList of
      Rectangle: (Height, Width: Real);
      Triangle: (Side1, Side2, Angle: Real);
      Circle: (Radius: Real);
      Ellipse, Other: ();
   end;

根据您的需求,类层次结构可能是更好的选择。 - Uli Gerhardt
1个回答

8
你需要添加一个形状字段,如下所示:
type
    TShapeList = (Rectangle, Triangle, Circle, Ellipse, Other);
    TFigure = record
    case Shape: TShapeList of
      Rectangle: (Height, Width: Real);
      Triangle: (Side1, Side2, Angle: Real);
      Circle: (Radius: Real);
      Ellipse, Other: ();
   end;

请注意Shape字段。
另外请注意这并不意味着Delphi会自动进行检查 - 您需要自己进行检查。例如,您可以将所有字段设置为私有,并仅通过属性进行访问。在它们的getter/setter方法中,您可以根据需要分配和检查Shape字段。以下是一个示例:
type
  TShapeList = (Rectangle, Triangle, Circle, Ellipse, Other);

  TFigureImpl = record
    case Shape: TShapeList of
      Rectangle: (Height, Width: Real);
      Triangle: (Side1, Side2, Angle: Real);
      Circle: (Radius: Real);
      Ellipse, Other: ();
  end;

  TFigure = record
  strict private
    FImpl: TFigureImpl;

    function GetHeight: Real;
    procedure SetHeight(const Value: Real);
  public
    property Shape: TShapeList read FImpl.Shape;
    property Height: Real read GetHeight write SetHeight;
    // ... more properties
  end;

{ TFigure }

function TFigure.GetHeight: Real;
begin
  Assert(FImpl.Shape = Rectangle); // Checking shape
  Result := FImpl.Height;
end;

procedure TFigure.SetHeight(const Value: Real);
begin
  FImpl.Shape := Rectangle; // Setting shape
  FImpl.Height := Value;
end;

我将记录分为两种类型,否则编译器无法接受所需的可见性修饰符。此外,我认为这样更易读,并且GExperts代码格式化程序不会出错。 :-)

现在,像这样的内容将违反断言:

procedure Test;
var
  f: TFigure;
begin
  f.Height := 10;
  Writeln(f.Radius);
end;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接