作为。elegancre 在这里是什么意思?实施的优雅还是使用的优雅或CPI效率或可维护性?优雅是一个非常模糊的词...
我认为使其更易于使用的明显方法 是将类型转换为可用于ExtBoolean1 or (ExtBoolean2 and True)
.
然而,所需的功能可能在 Delphi 2006 之前或不足(本身相当错误的版本),所以带上你DUnit
并做很多测试..
要列出要使用的功能及其描述:
- 增强记录:什么时候应该在 Delphi 中使用增强记录类型而不是类?和http://delphi.about.com/od/adptips2006/qt/newdelphirecord.htm和手册
- 操作重载,包括隐式类型转换:将“增强记录”分配给普通“数据类型”变量时,我应该重载什么运算符?Delphi和手册中的运算符重载
- 函数内联:delphi和手册中 inline 关键字的用途
概述其中一些想法:
type
TExtBoolean = record
Value: (ebUnknown, ebTrue, ebFalse);
function IsNull: boolean; inline;
function Defined: boolean; inline;
class operator Implicit ( from: boolean ): TExtBoolean; inline;
class operator Implicit ( from: TExtBoolean ): boolean;
class operator LogicalAnd( Value1, Value2: TExtBoolean ): TExtBoolean;
class operator LogicalAnd( Value1: TExtBoolean; Value2: boolean): TExtBoolean; inline;
class operator LogicalAnd( Value1: boolean; Value2: TExtBoolean ): TExtBoolean;
....
end;
const Unknown: TExtBoolean = (Value: ebUnknown);
...
var v1: TExtBoolean;
v1 := False;
v1 := True;
v1 := Unknown;
...
class operator TExtBoolean.Implicit ( from: boolean ): TExtBoolean;
begin
if from
then Result.Value := ebTrue
else Result.Value := ebFalse
end;
class operator TExtBoolean.Implicit ( from: TExtBoolean ): Boolean;
begin
case from.Value of
ebTrue: Result := True;
ebFalse: Result := False;
else raise EConvertError.Create('....');
end;
function TExtBoolean.Defined: boolean;
begin
Result := (Self.Value = ebTrue) or (Self.Value = ebFalse);
end;
// this implementation detects values other than ebTrue/ebFalse/ebUnkonwn
// that might appear in reality due to non-initialized memory garbage
// since hardware type of Value is byte and may be equal to 3, 4, ...255
function TExtBoolean.IsNull: boolean;
begin
Result := not Self.Defined
end;
class operator TExtBoolean.And( Value1, Value2: TExtBoolean ): TExtBoolean;
begin
if Value1.IsNull or Value2.IsNull
then Result.Value := eb.Undefined
else Result := boolean(Value1) and boolean(Value2);
// Or, sacrificing readability and safety for the sake of speed
// and removing duplicate IsNull checks
// else Result := (Value1.Value = ebTrue) and (Value2.Value = ebTrue);
end;
class operator TExtBoolean.LogicalAnd( Value1, TExtBoolean; Value2: boolean): TExtBoolean;
begin
Result := Value2 and Value1;
end;
class operator TExtBoolean.LogicalAnd( Value1: boolean; Value2: TExtBoolean ): TExtBoolean;
begin
if Value2.IsNull
then Result := Value2
else Result := Value1 and (Value2.Value = ebTrue);
// or if to accept a duplicate redundant check for readability sake
// and to avert potential later erros (refactoring, you may accidentally remove the check above)
// else Result := Value1 and boolean (Value2);
end;
ETC
PS。上面未指定的检查是故意悲观的,倾向于在坏的方面犯错。它是针对未初始化变量和未来可能发生的变化的防御,添加的状态多于三个。虽然 thise 似乎保护过度,但至少 Delphi XE2 同意 mee:请参阅类似情况下的警告:
program Project20; {$APPTYPE CONSOLE}
uses System.SysUtils;
type enum = (e1, e2, e3);
var e: enum;
function name( e: enum ): char;
begin
case e of
e1: Result := 'A';
e2: Result := 'B';
e3: Result := 'C';
end;
end;
// [DCC Warning] Project20.dpr: W1035 Return value of function 'name' might be undefined
begin
for e := e1 to e3
do Writeln(name(e));
ReadLn;
end.