5

さまざまな列挙型の選択を渡すことができるプロシージャを作成する必要があります。

type
  TEnumOne = (eOneFlagOne, eOneFlagTwo);
  TEnumTwo = (eTwoFlagOne, eTwoFlagTwo);

メソッドは異なる列挙型を取る必要があります。

Process([eOneFlagOne, eTwoFlagTwo]);

私は次のように実装しようとしています:

// does not work!
procedure Process(const Enums: array of Variant);
var aValue; Variant
begin
  for aValue in Enums do
  begin
    // of course, can't work...
    if aValue is TEnumOne then
  end; 
end;

では、Variant の代わりに選択できるタイプはありますか? それとも、別のアプローチですか?

4

4 に答える 4

10

パスカルの美しさに出会う。

おそらくあなたがやろうとしていることの実例を次に示します。

program Project34; {$APPTYPE CONSOLE}

type
  TEnum=(eOneFlagOne,eOneFlagTwo,eTwoFlagOne,eTwoFlagTwo);
  TEnumSet=set of TEnum;

const
  cEnumOne=[eOneFlagOne,eOneFlagTwo];
  cEnumTwo=[eTwoFlagOne,eTwoFlagTwo];

procedure Process(const Enums: TEnumSEt);
var e:TEnum;
begin
  for e in Enums do
    WriteLn(ord(e));
end;

begin
  Process([eOneFlagOne, eTwoFlagTwo]);
  Process(cEnumOne);
  Process(cEnumTwo);
end.

このように定数を宣言することもできます。多分それはより明確です:

const
  cEnumOne:TEnumSet=[eOneFlagOne,eOneFlagTwo];
  cEnumTwo:TEnumSet=[eTwoFlagOne,eTwoFlagTwo];
于 2012-06-19T23:58:04.147 に答える
4

率直に言うと、このように言葉を曲げようとしているときは、通常、そのアプローチがおそらく間違っていることを意味します。(常にではありませんが、通常)より良い設計オプションがあるかもしれないので、解決しようとしている問題を知りたいです。

あなたの問題について私たちが知っていることはほとんどありませんが、異なるシグネチャを持つ 2 つの関数を作成することをお勧めします。
または
、必要なロジック ブランチが互いに十分に類似している場合は、enum 型をジェネリック パラメーターとして使用して、ジェネリック メソッドを作成できます(Delphi 2009 以降を想定)。

...
procedure Process<T>(const enumParam : T) // Add a generic constraint here as well
begin
...
end;

ただし、2つの異なる方法がおそらく最良の選択肢(またはまったく別のもの)である可能性が高いと思われます

于 2012-06-19T23:56:13.300 に答える
1

RRUZ は彼の回答を削除しました。これは型安全性を備えた再加工版です。RTTI は、さまざまな列挙型定数を識別するために使用されます。

function EnumToString(const TypeInfo : pTypeInfo; Ix : Integer) : string;
begin
  Result := GetEnumName(TypeInfo, ix); 
end;

procedure Process( const Args : array of string);
var
  LIndex,ix : integer;
  EnumOne : TEnumOne;
  EnumTwo : TEnumTwo;
begin
  for LIndex := 0 to High(Args) do begin
    ix := GetEnumValue( TypeInfo(TEnumOne), Args[LIndex]);
    if (ix <> -1) then
    begin
      EnumOne := TEnumOne( ix); 
      // do something with EnumOne
      ...
      continue;
    end;

    ix := GetEnumValue( TypeInfo(TEnumTwo), Args[LIndex]);
    if (ix <> -1) then
    begin
      EnumTwo := TEnumTwo( ix); 
      // do something with EnumTwo
      ...
      continue;
    end; 
    ... 
    etc

  end;        
end;

Process( [EnumToString(TypeInfo(TEnumOne),Ord(TEnumOne.eOneFlagOne)),
          EnumToString(TypeInfo(TEnumTwo),Ord(TEnumTwo.eTwoFlagTwo))]);
于 2012-06-20T14:22:19.223 に答える
0

別の方法は、それを1つの列挙型として保持することです。

TEnum = (eOneFlagOne, eOneFlagTwo, eTwoFlagOne, eTwoFlagTwo);

プロセス関数は次のようになります。

procedure Process(Enums: Array of TEnum);
var 
  aValue: TEnum;
begin
  for aValue in Enums do
  begin
    if aValue in [eOneFlagOne, eOneFlagTwo] then
      // Handle the eOne enums
    else if aValue in [eTwoFlagOne, eTwoFlagTwo] then
      // Handle the eTwo enums
  end; 
end;
于 2012-06-20T06:31:09.627 に答える