Могу ли я определить MyType, который может содержать только эти значения? - PullRequest
4 голосов
/ 05 ноября 2011

У меня есть такая проблема: если у меня есть, например, эти значения: «AA», «AB», «AC», «BC» - я могу определить MyType, который может содержать только эти значения?

Я хочу сделать в режиме, который:

type MyType = ... ; // something
var X: MyType;
begin
  x := 'AA' ;  // is valid, 'AA' is included in X 
  X := 'SS' ;  // not valid, 'SS' not is included in X, than raise an exception.
end; 

Как я могу решить это? Есть ли какое-то решение, напрямую использующее данные типа?

1 Ответ

11 голосов
/ 05 ноября 2011

Это на самом деле довольно просто, используя перегрузку оператора.

Do

type
  TMyType = record
  private
    type
      TMyTypeEnum = (mtAA, mtAB, mtAC, mtBC);
    var
      FMyTypeEnum: TMyTypeEnum;
  public
    class operator Implicit(const S: string): TMyType;
    class operator Implicit(const S: TMyType): string;
  end;

implementation

class operator TMyType.Implicit(const S: string): TMyType;
begin
  if SameStr(S, 'AA') then begin result.FMyTypeEnum := mtAA; Exit; end;
  if SameStr(S, 'AB') then begin result.FMyTypeEnum := mtAB; Exit; end;
  if SameStr(S, 'AC') then begin result.FMyTypeEnum := mtAC; Exit; end;
  if SameStr(S, 'BC') then begin result.FMyTypeEnum := mtBC; Exit; end;
  raise Exception.CreateFmt('Invalid value "%s".', [S]);
end;

class operator TMyType.Implicit(const S: TMyType): string;
begin
  case S.FMyTypeEnum of
    mtAA: result := 'AA';
    mtAB: result := 'AB';
    mtAC: result := 'AC';
    mtBC: result := 'BC';
  end;
end;

Теперь вы можете сделать

procedure TForm1.Button1Click(Sender: TObject);
var
  S: TMyType;
begin
  S := 'AA';                // works
  Self.Caption := S;

  S := 'DA';                // does not work, exception raised
  Self.Caption := S;
end;
...