2011-11-05 72 views
4

我有这个问题:例如,如果我有这些值:'AA','AB','AC','BC' - 我可以定义只包含这些值的MyType吗?我可以定义只能包含这些值的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; 

我怎样才能解决呢?有没有直接使用类型数据的解决方案?

+0

什么'型TMyType =(MTAA,MTAB,MTAC,MTBC)'? –

+0

使用枚举类型的编译时保护或属性设置程序的运行时保护 –

+0

但不是如常数,但作为字符串,例如:TMytype =('AA','AB','AC','BC')并确保如果将X定义为tmytype,那么X可以只假定该值,而对于其他值则会引发异常。 –

回答

11

这实际上很简单,使用运算符重载。

不要

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; 
+2

+1。干得好:) –

+0

+1。很好。非常感谢。是关于我想要的。再次感谢。 –

相关问题