Я пытаюсь записать функцию, которая берет любой TList и возвращает Строковое представление всех элементов TList.
Я попробовал функцию как так
function ListToString(list:TList<TObject>):String;
Это хорошо работает, кроме Вас не может передать a TList<String>
к нему.
E2010 Incompatible types: 'TList<System.TObject>' and 'TList<System.string>'
В Delphi Строкой не является Объект. Для решения этого я записал вторую функцию:
function StringListToString(list:TList<string>):String;
Действительно ли это - единственное решение? Там другие пути состоят в том, чтобы рассматривать Строку как более 'подобную объекту'?
В том же духе я также хотел записать, 'равняется' функции для сравнения двух TLists. Снова я сталкиваюсь с той же проблемой
function AreListsEqual(list1:TList<TObject>; list2:TList<TObject>):boolean;
Там какой-либо путь состоит в том, чтобы записать эту функцию (возможно, использование дженериков?), таким образом, это может также обработать a TList<String>
? Есть ли какие-либо другие приемы или 'методы наиболее успешной практики', о которых я должен знать при попытке создать код, который обрабатывает и Строки и Объекты? Или я просто создаю две версии каждой функции? Дженерики могут помочь?
Я происхождения Java, но теперь работаю в Delphi. Кажется, что они в последнее время добавляют много вещей к Delphi от мира Java (или возможно мир C#, который скопировал их с Java). Как добавление равняется () и хэш-код () к TObject и созданию платформы универсальных наборов и т.д. Я задаюсь вопросом, очень ли эти дополнения практичны, если Вы не можете использовать Строки с ними.
[редактирование: Кто-то упомянул TStringList. Я использовал это до настоящего времени, но я спрашиваю о TList. Я пытаюсь удаться, если использование TList для всего (включая Строки) является более чистым способом пойти.]
Ваша проблема не в том, что строка
и TObject
несовместимые типы (хотя они и есть), это то, что TList
и TList
являются несовместимыми типами, даже если x
и y
сами по себе нет. Причины сложны, но в основном это так.
Представьте, что ваша функция приняла TList
, а вы передали TList
, и это сработало. Но затем в своей функции вы добавили в список TIncompatibleObject
. Поскольку сигнатура функции знает, что она работает только со списком TObject, это работает, и вы внезапно нарушили инвариант, и когда вы попытаетесь перечислить этот список и использовать экземпляры TMyObject внутри, что-то может взорваться.
Если бы команда Delphi добавила поддержку ковариации и контравариантности для общих типов, вы могли бы сделать что-то подобное безопасно, но, к сожалению, они еще не дошли до этого.Надеюсь, мы скоро это увидим.
Но, возвращаясь к исходному вопросу, если вы хотите сравнить список строк, нет необходимости использовать дженерики; В Delphi есть специальный класс со списком строк под названием TStringList, находящийся в модуле Classes, который вы можете использовать. Он имеет множество встроенных функций для обработки строк, включая три способа объединения всех строк в одну строку: свойства Text, CommaText и DelimitedText.
Это не чище. Это хуже.Принципиально ПЛОХАЯ идея использовать TList
вместо TStringList
.
Не будет более чистым сказать «Я везде использую дженерики». Фактически, если вы хотите быть последовательными, используйте их Нигде. Избегайте их, как большинство разработчиков delphi избегают их, как чумы.
Все «списки» строк в VCL относятся к типу TStringList. Большинство коллекций объектов в большинстве приложений delphi используют TObjectList вместо шаблонных типов.
Не чище и непротиворечивее быть МЕНЬШЕ согласованности со всей платформой Delphi, выбирать какие-то странные вещи и стандартизировать их, когда только вы и только вы будете делать эту странную вещь.
На самом деле, я все еще не уверен, что использование дженериков безопасно.
Если вы начнете использовать TList, вы не сможете полностью скопировать его в свой Memo.Lines, который является TStringList, и вы создадите несовместимость типов зря, плюс вы потеряете дополнительную функциональность в TStringList . И вместо использования TStringList.Text вы должны придумать это для себя. Вы также теряете LoadFromFile и SaveToFile и многое другое. Массивы строк - это повсеместная вещь в Delphi, и они почти всегда являются TStringList. TList
не работает.