2010-05-26 17 views
6

我正在嘗試編寫一個接受任何TList並返回TList所有元素的字符串表示形式的函數。Delphi:處理字符串不是對象的事實

我試着像這樣

function ListToString(list:TList<TObject>):String; 

功能也能正常工作,但你不能越過TList<String>給它。

E2010 Incompatible types: 'TList<System.TObject>' and 'TList<System.string>' 

在Delphi中,字符串不是對象。爲了解決這個問題,我寫了第二個功能:

function StringListToString(list:TList<string>):String; 

這是唯一的解決方案嗎?是否有其他方法將字符串視爲更像'對象'?

以類似的方式,我也想寫一個'等號'函數來比較兩個TList。我再次遇到同樣的問題

function AreListsEqual(list1:TList<TObject>; list2:TList<TObject>):boolean; 

有什麼辦法來寫這個功能(可能使用泛型?),所以它也可以處理TList<String>?當嘗試創建處理字符串和對象的代碼時,我還應該瞭解其他任何技巧或「最佳實踐」嗎?或者我只是創建每個功能的兩個版本?泛型可以幫助嗎?

我來自Java背景,但現在在Delphi工作。看來他們最近從Java世界向Delphi添加了很多東西(或者是從Java複製它們的C#世界)。就像將equals()和hashcode()添加到TObject,並創建一個通用的集合框架等。我想知道如果這些添加是非常實用的,如果你不能使用字符串與他們。

[編輯:有人提到TStringList。到目前爲止我已經使用過,但我在問TList。我試圖找出是否使用從TList的一切(包括字符串)是去一個更清潔的方式。]

+5

我真的不會付出太多的努力來支持'TList ';沒有人使用它,因爲[它不如'TStringList'](http://stackoverflow.com/questions/279471/tstringlist-vs-tliststring)。將注意力集中在別處。 – 2010-05-26 06:04:12

+0

TList 的字符串表示怎麼看? – 2013-04-25 09:26:56

回答

7

你的問題不在於stringTObject是不兼容的類型,(儘管他們是)它是TList<x>TList<y>是不兼容的類型,即使它們本身不是xy。原因很複雜,但基本上是這樣。

想象一下,您的功能接受了TList<TObject>,並且您通過了TList<TMyObject>並且工作正常。但是在你的函數中,你添加了一個TIncompatibleObject到列表中。由於函數簽名只知道它正在處理一個TObject列表,所以它會起作用,並且突然間你違反了一個不變量,當你試圖枚舉這個列表並使用TMyObject實例時,事情可能會爆炸。

如果德爾菲團隊增加了對泛型類型協變和逆變的支持,那麼你就可以安全地做這樣的事情,但不幸的是他們還沒有得到它。希望我們很快會看到它。

但回到你原來的問題,如果你想比較一個字符串列表,沒有必要使用泛型; Delphi有一個名爲TStringList的特定的字符串列表類,可以在Classes單元中找到,您可以使用它。它有很多用於字符串處理的內置功能,包括三種將所有字符串連接成單個字符串的方式:Text,CommaText和DelimitedText屬性。

+1

我忘了加我說的是TList ,而不是TStringList。在D2010之前,我使用TStringList,但我試圖從一個更統一的API(即TList)轉移到某些東西。我將編輯我的問題。 – awmross 2010-05-26 03:40:21

+0

所以我不能將例如TList 傳遞給我的ListToString函數。我懂了!有沒有另外一種方法來編寫ListToString的函數簽名,以便我*可以傳遞一個'TList '? – awmross 2010-05-26 04:21:10

+2

@awmross:嗯,你可以給函數本身一個通用類型。 '函數ListToString (list:TList ):String;'這會工作。但是編譯器不能假設T的本質,所以你不能把它當作一個對象。 (除非在T上放置類約束或特定類約束,但是不能使用字符串。)基本上,泛型是有用的,但它們不是一切的最終答案。 – 2010-05-26 04:32:27

0

這並不乾淨。它更糟。使用TList<String>代替TStringList是一個根本不好的想法。

說「我在各地使用泛型」並不是很乾淨。事實上,如果你想保持一致,可以使用它們。避免它們,就像大多數delphi開發人員避免它們一樣,瘟疫。

VCL中字符串的所有「列表」都是TStringList類型。大多數delphi應用程序中的大多數對象集合都使用TObjectList,而不是模板類型。

與整個德爾福平臺相一致,並且挑選出一些奇怪的東西,並且對它進行標準化,什麼時候會是你,以及你自己,做這個古怪的事情,這不是更清潔和更一致的。

事實上,我仍然不確定泛型是否可以安全使用。

如果您開始使用TList,您將無法將其完整地複製到您的Memo.Lines,它是一個TStringList,並且您將創建一個類型不兼容性,此外,您將失去額外的功能TStringList中。而不是使用TStringList.Text,你必須爲自己創造。你也會失去LoadFromFile和SaveToFile等等。字符串數組在Delphi中是無處不在的,它們幾乎總是一個TStringList。 TList<String>是跛腳。

+1

與現有庫的互操作性當然是需要考慮的事情。與TStringList的不一致在於,如果你想要一個除String以外的其他列表,你必須使用與TStringList完全不兼容的東西(例如,g TObjectList)。 – awmross 2010-06-01 01:51:23

+0

你做錯了。 Delphi字符串類型是基本類型。這聽起來像你想讓他們成爲對象。但他們不是。整數也不是一種對象。學會與之共處。 – 2010-06-14 17:54:28

+0

並非java中的所有類型都有一個共同的根,或者 – 2011-03-24 23:41:57

1

雖然它遠非最佳,但您可以創建字符串包裝類,可能包含一些其他有用的函數,這些函數對字符串進行操作。 Here就是一個示例類,應該對其進行增強,以便簡化內存管理,例如使用these methods

我只是建議你的問題的解決方案,我不同意爲了一致性的一致性會使代碼更好。如果你需要它, Delphi 對象pascal可能不是選擇的語言。