简体   繁体   English

delphi中的变体记录

[英]variant record in delphi

I am just trying to learn variant records.Can someone explain how Can I check shape in record whether it is rectangle/Triangle etc. or any good example with implementation available ?我只是想学习变体记录。有人可以解释我如何检查记录中的形状是矩形/三角形等还是任何可用的实现的好例子? I had checked variants record here but no implementation available..我在这里检查了变体记录,但没有可用的实现..

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;

You have to add a field for the shape like so:您必须为该形状添加一个字段,如下所示:

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;

Note the Shape field.注意Shape字段。

Also note that this doesn't imply any automatic checking by Delphi - you have to do that yourself.另请注意,这并不意味着 Delphi 进行任何自动检查 - 您必须自己进行。 For example, you could make all the fields private and allow access only through properties.例如,您可以将所有字段设为私有并仅允许通过属性进行访问。 In their getter/setter methods you could assign and check the Shape field as needed.在他们的 getter/setter 方法中,您可以根据需要分配和检查Shape字段。 Here's a sketch:这是一个草图:

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;

I split the record in two types because otherwise the compiler wouldn't accept the visibility specifiers as they are needed.我将记录分成两种类型,否则编译器将不会在需要时接受可见性说明符。 Also I think it's more readable and the GExperts code formatter doesn't choke on it.此外,我认为它更具可读性,并且 GExperts 代码格式化程序不会因此而窒息。 :-) :-)

Now something like this would violate an assertion:现在这样的事情会违反断言:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM