如何实现类型安全的COM枚举?

时间:2020-03-05 18:43:56  来源:igfitidea点击:

在COM方案中,如何在Delphi中实现类型安全的枚举?基本上,我想用封装在class中的一组静态最终对象引用替换枚举的一组原始常量。 。
在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枚举之外,我们还有实现枚举的更好方法吗?

解决方案

回答

本地Delphi枚举有什么问题?它们是类型安全的。

type
  TMyEnum = (Item1, Item2, Item3);

if MyEnum <> Item1 then...

从Delphi 2005开始,我们可以在一个类中使用const,但是Delphi 5则不能。

type
  TMyEnum = sealed class
  public
    const Item1 = 0;
    const Item2 = 1;
    const Item3 = 2;
  end;

回答

本机Delphi枚举已经是类型安全的。 Java枚举是该语言的一项创新,因为在此之前根本没有枚举。但是,也许我们是说不同的功能枚举值以其类型名称作为前缀。

即将发布的Delphi 2009和用于.NET产品的Delphi的最新版本都支持一个称为范围枚举的新指令。看起来像这样:

{$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.

回答

现在,我们为我们提供了有关问题性质的更多线索,即提及COM,我想我理解意思。 COM只能封送Delphi在COM服务器和客户端之间知道的类型的子集。我们可以在TLB编辑器中定义枚举,但是它们都是TOleEnum类型,基本上是整数类型(LongWord)。我们可以将类型设为TOleEnum的变量设为所需的任何整数值,并将不同的枚举类型的值彼此分配。不是真正的安全类型。

我想不出为什么Delphi的COM不能使用类型安全的枚举的原因,但事实并非如此。恐怕对此无能为力。也许即将发布的Delphi 2009版本中的TLB编辑器中的更改可能会改变这种情况。

记录:不使用TLB编辑器时,Delphi完全能够与以类型安全的枚举作为参数的方法建立接口。

回答

我想我知道为什么Borland选择在TLB编辑器中不使用类型安全的枚举。 COM中的枚举可以是不同的值,而Delphi仅因为Delphi 6(我认为)可以做到这一点。

type
  TSomeEnum = (Enum1 = 1, Enum2 = 6, Enum3 = 80);  // Only since Delphi 6