重载枚举数组

时间:2016-02-16 16:35:46

标签: delphi enums delphi-2007 overloading

我试图通过使用重载过程来创建一个带有无类型参数类型安全的旧API,比如说

// old, untyped API:
procedure DoItUntyped(var AEle; ASize: Integer);
begin
  Writeln(ASize);
  // Doing the real work (including modifications to AEle, therefore the "var")
end;

// New typed overloads:
procedure DoIt(var AEle: Word); overload;
begin
  DoItUntyped(AEle, SizeOf(AEle));
end;

procedure DoIt(var AEle: Byte); overload;
begin
  DoItUntyped(AEle, SizeOf(AEle));
end;

我现在可以这样使用:

procedure Test;
var
  w: Word;
  b: Byte;
  e: TTextLineBreakStyle;
begin
  DoIt(w);
  DoIt(b);
  DoIt(Byte(e));
end;

请注意,它甚至适用于枚举类型(如e),只需很少的努力(一次演员)和非常类型安全(例如DoIt(Word(e));无法编译)。

现在我想将这种技术扩展到数组。这对于内置类型很容易:

procedure DoIt(var AEle: array of Word); overload;
begin
  DoItUntyped(AEle, SizeOf(AEle));
end;

procedure DoIt(var AEle: array of Byte); overload;
begin
  DoItUntyped(AEle, SizeOf(AEle));
end;

procedure Test;
var
  w3: array[0..3] of Word;
  b3: array[0..3] of Byte;
  w9: array[0..9] of Word;
  b9: array[0..9] of Byte;
begin
  DoIt(w3);
  DoIt(b3);
  DoIt(w9);
  DoIt(b9);
end;

但是对于枚举数组来说它变得很难看。我可以介绍帮手类型:

procedure Test;
type
  TB3 = array[0..3] of Byte;
  TB9 = array[0..9] of Byte;
var
  e3: array[0..3] of TTextLineBreakStyle;
  e9: array[0..9] of TTextLineBreakStyle;
begin
  DoIt(TB3(e3));
  DoIt(TB9(e9));
end;

但我需要为每种类型和数组长度提供一种帮助器类型。另一种方法可能是为数组长度添加一个单独的参数,但这需要重复调​​用:

procedure DoItArray(var AFirstEle: Word; ALength: Integer); overload;
begin
  DoItUntyped(AFirstEle, SizeOf(AFirstEle) * ALength);
end;

procedure DoItArray(var AFirstEle: Byte; ALength: Integer); overload;
begin
  DoItUntyped(AFirstEle, SizeOf(AFirstEle) * ALength);
end;

procedure Test;
var
  e3: array[0..3] of TTextLineBreakStyle;
  e9: array[0..9] of TTextLineBreakStyle;
begin
  DoItArray(Byte(e3[Low(e3)]), Length(e3));
  DoItArray(Byte(e9[Low(e9)]), Length(e9));
end;

到目前为止,最佳解决方案似乎也为(可能很多)枚举类型添加了重载:

procedure DoIt(var AEle: TTextLineBreakStyle); overload;
procedure DoIt(var AEle: array of TTextLineBreakStyle); overload;

在我开始之前,我想知道是否有人有更少重复的想法。请注意,我们仍然必须使用D2007,所以没有泛型。

1 个答案:

答案 0 :(得分:1)

从重载中删除var说明符,除非您希望函数修改传入的变量,否则不需要它:

// old, untyped API:
procedure DoItUntyped(var AEle; ASize: Integer);
begin
  Writeln(ASize);
  // Doing the real work
end;

// New typed overloads:
procedure DoIt(AEle: Word); overload;
begin
  DoItUntyped(AEle, SizeOf(AEle));
end;

procedure DoIt(AEle: Byte); overload;
begin
  DoItUntyped(AEle, SizeOf(AEle));
end;

procedure Test;
var
  w: Word;
  b: Byte;
  e: TTextLineBreakStyle;
begin
  DoIt(w);
  DoIt(b);
  DoIt(Byte(e));
end;

然后可以像这样完成数组:

procedure DoIt(AEle: array of Word); overload;
begin
  DoItUntyped(PWord(AEle)^, Length(AEle) * SizeOf(Word));
end;

procedure DoIt(AEle: array of Byte); overload;
begin
  DoItUntyped(PByte(AEle)^, Length(AEle) * SizeOf(Byte));
end;

procedure DoIt(AEle: array of TTextLineBreakStyle); overload;
var
  PTextLineBreakStyle = ^TTextLineBreakStyle;
begin
  DoItUntyped(PTextLineBreakStyle(AEle)^, Length(AEle) * SizeOf(TTextLineBreakStyle));
end;

procedure Test;
var
  w3: array[0..3] of Word;
  b3: array[0..3] of Byte;
  w9: array[0..9] of Word;
  b9: array[0..9] of Byte;
  e3: array[0..3] of TTextLineBreakStyle;
  e9: array[0..9] of TTextLineBreakStyle;
begin
  DoIt(w3);
  DoIt(b3);
  DoIt(w9);
  DoIt(b9);
  DoIt(e3);
  DoIt(e9);
end;
相关问题