题
我如何在 COM 场景中在 Delphi 中实现类型安全枚举?基本上,我想用封装在类中的一组静态最终对象引用替换一组枚举的原始常量?。在Java中,我们可以做这样的事情:
public final class Enum
{
public static final Enum ENUMITEM1 = new Enum ();
public static final Enum ENUMITEM2 = new Enum ();
//...
private Enum () {}
}
并使用自定义的枚举类型进行比较:
if (anObject != Enum.ENUMITEM1) ...
我目前正在使用旧的 Delphi 5,我想在接口上声明一些枚举参数,不允许客户端对象传递整数(或长整型)类型来代替所需的枚举类型。除了使用本机delphi枚举之外,您还有更好的方法来实现枚举吗?
解决方案
现在您已经向我们提供了有关您问题性质的更多线索,即提到 COM,我想我明白您的意思。COM 只能在 COM 服务器和客户端之间编组 Delphi 所知道的类型的子集。您可以在 TLB 编辑器中定义枚举,但这些都是 TOleEnum 类型,它基本上是整数类型 (LongWord)。您可以将 TOleEnum 类型的变量设置为任何您想要的整数值,并将不同枚举类型的值相互分配。并不是真正的类型安全。
我想不出 Delphi 的 COM 不能使用类型安全枚举的原因,但事实并非如此。恐怕对此无能为力。也许即将发布的 Delphi 2009 版本中 TLB 编辑器的更改可能会改变这一点。
作为记录:当不使用 TLB 编辑器时,Delphi 完全能够与以类型安全枚举作为参数的方法进行接口。
其他提示
本机 Delphi 枚举已经是类型安全的。Java 枚举是该语言的一项创新,因为之前它根本没有枚举。但是,也许您指的是不同的功能 - 枚举值以其类型名称为前缀。
即将推出的 Delphi 2009 以及 Delphi for .NET 产品的最后一个版本支持称为作用域枚举的新指令。它看起来像这样:
{$APPTYPE CONSOLE}
{$SCOPEDENUMS ON}
type
TFoo = (One, Two, Three);
{$SCOPEDENUMS OFF}
var
x: TFoo;
begin
x := TFoo.One;
if not (x in [TFoo.Two, TFoo.Three]) then
Writeln('OK');
end.
本机 Delphi 枚举有什么问题?它们是类型安全的。
type
TMyEnum = (Item1, Item2, Item3);
if MyEnum <> Item1 then...
从 Delphi 2005 开始,您可以在类中拥有常量,但 Delphi 5 不能。
type
TMyEnum = sealed class
public
const Item1 = 0;
const Item2 = 1;
const Item3 = 2;
end;
我想我知道为什么 Borland 选择不在 TLB 编辑器中使用类型安全枚举。COM 中的枚举可以是不同的值,而 Delphi 只有从 Delphi 6(我认为)才能做到这一点。
type
TSomeEnum = (Enum1 = 1, Enum2 = 6, Enum3 = 80); // Only since Delphi 6