Florian Koch
Florian Koch

Reputation: 1502

Convert Integer to Enum in property getter/setter

I currently have an option management which works with properties, that use all the same getter/setter method but with an index.

This works fine for Ints and Bools, but I'd like to get this working for enums, too.

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;

This is working so far, and now my problem:

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

I marked the problems in the code. Can I somehow cast the Integer values returned by the getters/setters to the matching enum for each property?

For those who read the old question:
I decided to just use the same getter/setter for the enums, cause in the end they get saved as Integers, too. If I need to cast inside the getters somehow, I'll add them again, but i hoped for a solution inside the property-declaration.

Upvotes: 2

Views: 668

Answers (1)

David Heffernan
David Heffernan

Reputation: 612794

Regarding your update, you want to use code like this:

class property Enum1: TEnum1 index kEnum1 read GetOptionsValueInt; 

That fails to compile because GetOptionsValueInt returns a value of type Integer. Since the property has type TEnum1, that is a simple type mismatch. In order to have a property of type TEnum1, the getter must be a function that returns a value of type TEnum1.

If each of these properties has a different type, then you cannot share getter and setter. Shared indexed getters and setters can only be used for properties that share a common type. Since it looks like none of these properties share a type, you will not be able to share getters and setters.


Original answer to original question

You don't show all the declarations, so it's hard for us to know why your code does not compile. We don't know what FOptionsListeEnum is, and we don't know what Wert() is.

However, here's a complete program that demonstrates that enumerated types can be used as indexes for indexed properties:

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

So, that makes it clear that there's no issue using enumerated types as indices. In which case, what is your problem. Let's look at the code you have:

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;

If Ord(FOptionsListeEnum[aOption].Wert()) does not compile with a type mismatch error, then it would seem that Wert() is not an ordinal value.

As for aOption(aWert) that makes no sense at all. That can never compile. Perhaps you meant TEnumOptionen(aWert) but that also makes no sense. Why would the value be of the same type used to index the possible options.

I hope that the code above shows that the issue is not related to enumerated types as indexers and is in fact of a rather more prosaic nature.

Upvotes: 3

Related Questions