Arrays
можно индексировать с помощью пользовательских перечислимых типов. Например:
type
TIndexValue = (ZERO = 0, ONE, TWO, THREE, FOUR);
var
MyArray: array[Low(TIndexValue) .. High(TIndexValue)] of String;
Затем на элементы из этого массива можно ссылаться, используя значения TIndexValue
в качестве индекса:
MyArray[ZERO] := 'abc';
Я пытаюсь получить ту же общую функциональность с помощью файла TStringList
.
Одним из простых решений является приведение каждого значения индекса к типу Integer
во время ссылки:
MyStringList[Integer(ZERO)] := 'abc';
Другое решение (чтобы скрыть все приведения) состоит в том, чтобы создать подкласс TStringList
и отложить все приведения к подпрограммам этого подкласса, которые обращаются к унаследованному свойству Strings
:
type
TIndexValue = (ZERO = 0, ONE, TWO, THREE, FOUR);
type
TEIStringList = class(TStringList)
private
function GetString(ItemIndex: TIndexValue): String;
procedure SetString(ItemIndex: TIndexValue; ItemValue: String);
public
property Strings[ItemIndex: TIndexValue]: String
read GetString write SetString; default;
end;
function TEIStringList.GetString(ItemIndex: TIndexValue): String;
begin
Result := inherited Strings[Integer(ItemIndex)];
end;
procedure TEIStringList.SetString(ItemIndex: TIndexValue; ItemValue: String);
begin
inherited Strings[Integer(ItemIndex)] := ItemValue;
end;
Это прекрасно работает для одной реализации, использующей перечисляемый тип TIndexValue
.
Однако я хотел бы повторно использовать эту же логику или подкласс для нескольких разных объектов TStringList
, которые индексируются по разным перечисляемым типам, без необходимости определять подклассы TStringList
для каждого возможного перечисляемого типа.
Возможно ли что-то подобное? Я подозреваю, что мне, возможно, придется зависеть от Delphi Generics, но мне было бы очень интересно узнать, что есть более простые способы добиться этого.
array [TIndexValue] of string
несовершенен? - person David Heffernan   schedule 20.02.2012TStringList
вместо массива строк? Я написал несколько служебных функций, которые зависят от списков, а не от массивов, и я хотел бы сохранить их реализацию прежней. - person ardnew   schedule 20.02.2012TStringList
? может бытьTDictionary<TIndexValue, string>
лучше? - person teran   schedule 20.02.2012TMyStringList<T : ordinal>
сproperty MyItems[idx : T] : string read...
, а затем преобразоватьT
в целое число в методе get. но в любом случае, если вам нужен только контейнер для хранения строки и доступа к ней с помощью вашегоTIndexValue
, тогдаTDictionary
будет лучшим решением; - person teran   schedule 20.02.2012ordinal
не работает, а даже если бы и работало - Enum не является порядковым номером; его значения - person Chris   schedule 20.02.2012array properties
в прекрасном мануале. В качестве индекса можно использовать практически любой тип! Однако в вашей идее есть недостаток, Count теряет смысл и всегда должен быть равен High (TIndexOrdinal) - Low (TIndexOrdinal) + 1. - person OnTheFly   schedule 20.02.2012TStringList
, а неarray
. Решениеarray
уже было опубликовано в вопросе. Крис говорил, чтоT
не обязательно является порядковым типом, поэтому приведениеInteger
недопустимо. - person ardnew   schedule 20.02.2012array[TIndexType] of string
. TList‹T›, TStringList и т. д. здесь не имеют преимуществ. - person Rudy Velthuis   schedule 21.02.2012