【问题标题】:Convert Integer to Enum in property getter/setter在属性 getter/setter 中将整数转换为枚举
【发布时间】:2014-07-15 09:24:01
【问题描述】:

我目前有一个与属性一起使用的选项管理,它使用所有相同的 getter/setter 方法,但带有一个索引。

这适用于 Ints 和 Bools,但我想让它也适用于枚举。

TIntegerOptions = (kInt1, kInt2, kInt3);

class property Integer1: Integer index kInt1 read GetOptionsValueInt write SetOptionsValueInt;
class property Integer2: Integer index kInt2 read GetOptionsValueInt write SetOptionsValueInt;
class property Integer3: Integer index kInt3 read GetOptionsValueInt write SetOptionsWertInt;

FOptionsListInt: array[TIntegerOptions] of IniIntObject;  // Objects contain Inifile read&save functionalities
...

class function GetOptionsValueInt(const aOption: TIntegerOptions) : Integer
begin
  Result := Ord(FOptionsListInt[aOption].GetValue());
end;

class procedure SetOptionsValueInt(const aOption: TIntegerOptions; const aValue: Integer);
begin
  FOptionslistInt[aOption].ChangeTo(aValue);
end;

到目前为止这是有效的,现在我的问题是:

TEnumOptions = (kEnum1, kEnum2, kEnum3);
TEnum1 = (e1o1, e1o2, e1o3);
TEnum2 = (e2o1, e2o2, e2o3);
TEnum3 = (e3o1, e3o2, e3o3);

// these props fail because my functions return / excpect Integers, not the matching Enums
class property Enum1: TEnum1 index kEnum1 read GetOptionsValueInt write SetOptionsValueEnum; 
class property Enum2: TEnum2 index kEnum2 read GetOptionsValueInt write SetOptionsValueEnum;
class property Enum3: TEnum3 index kEnum3 read GetOptionsValueInt write SetOptionsValueEnum;

FOptionsListEnum: array[TEnumOptions] of IniIntObject; // Objects contain Inifile read&save functionalities

我在代码中标记了问题。我可以以某种方式将 getter/setter 返回的整数值转换为每个属性的匹配枚举吗?

对于那些阅读旧问题的人:
我决定对枚举使用相同的 getter/setter,因为最终它们也被保存为整数。如果我需要以某种方式在 getter 中进行转换,我会再次添加它们,但我希望在属性声明中找到解决方案。

【问题讨论】:

    标签: delphi casting enums delphi-xe5


    【解决方案1】:

    关于你的更新,你想使用这样的代码:

    class property Enum1: TEnum1 index kEnum1 read GetOptionsValueInt; 
    

    编译失败,因为GetOptionsValueInt 返回一个Integer 类型的值。由于该属性的类型为TEnum1,这是一个简单的类型不匹配。为了拥有TEnum1 类型的属性,getter 必须是返回TEnum1 类型值的函数。

    如果这些属性中的每一个都有不同的类型,那么您就不能共享 getter 和 setter。共享索引的 getter 和 setter 只能用于共享公共类型的属性。由于看起来这些属性都不共享一个类型,因此您将无法共享 getter 和 setter。


    原始问题的原始答案

    您没有显示所有声明,因此我们很难知道您的代码为什么无法编译。我们不知道FOptionsListeEnum 是什么,我们也不知道Wert() 是什么。

    但是,这里有一个完整的程序,它演示了枚举类型可以用作索引属性的索引:

    {$APPTYPE CONSOLE}
    
    type
      TMyEnum = (evOne, evTwo);
    
      TMyClass = class
      private
        class function GetValue(const Option: TMyEnum): Integer; static;
      public
        class property ValueOne: Integer index evOne read GetValue;
        class property ValueTwo: Integer index evTwo read GetValue;
      end;
    
    class function TMyClass.GetValue(const Option: TMyEnum): Integer;
    begin
      Result := ord(Option);
    end;
    
    begin
      Writeln(TMyClass.ValueOne);
      Writeln(TMyClass.ValueTwo);
    end.
    

    因此,这清楚地表明使用枚举类型作为索引没有问题。在这种情况下,你的问题是什么。让我们看看你的代码:

    class function TKmpOption.GetOptionsWertEnum(const aOption: TEnumOptionen): Integer;
    begin
      Result := Ord(FOptionsListeEnum[aOption].Wert());
    end;
    
    class procedure TKmpOption.SetOptionsWertEnum(const aOption: TEnumOptionen; const aWert: Integer);
    begin
      FOptionslisteEnum[aOption].Aendern(aOption(aWert));
    end;
    

    如果Ord(FOptionsListeEnum[aOption].Wert()) 在编译时没有出现类型不匹配错误,那么Wert() 似乎不是一个序数值。

    至于aOption(aWert),这完全没有意义。那永远无法编译。也许您的意思是TEnumOptionen(aWert),但这也没有意义。为什么值的类型与用于索引可能选项的类型相同。

    我希望上面的代码表明这个问题与作为索引器的枚举类型无关,实际上是比较平淡的。

    【讨论】:

    • 很抱歉,我会尽快添加更多代码以更好地解释问题
    • @David Heffernan:OP 是否缺少允许将枚举类型用作函数的构造?我的意思是函数 GetEnum(Value: Integer): TAnEnum;开始结果 := TAnEnum(Value);结束;
    • 你是对的,setter 中的代码完全关闭了——我自己有点困惑。我将使用电脑(刚刚通过手机在线)并使用 moee 代码和假名更新问题,以便更容易理解 - atm 真的是一团糟,对此感到抱歉
    • 好的,非常感谢。我真的希望有可能以某种方式让 getter/setter 通用。看来我必须坚持正常的方式......
    猜你喜欢
    • 1970-01-01
    • 2017-10-30
    • 1970-01-01
    • 2014-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多