2012-01-20 12 views
11

मैं पता है कि इस विधि कॉल करता हैं:TStringList के addObject विधि

stringList.addObject(String,Object); 

मैं भी पता है कि इस संपत्ति करता हैं:

stringList.Objects[i] 

यह कुंजी, मान युग्म की तरह लग रहा है, जबकि जोड़ने। लेकिन एक लूप में पुनर्प्राप्त करते समय क्या प्राप्त किया जाता है?

मैं आइटम भी देखता हूं [i] कॉल।

मैं टीस्ट्रिंगलिस्ट ऑपरेशंस और टीएलआईस्ट ऑपरेशंस से उलझन में हूं।

+1

यह वास्तव में प्राचीन पूर्व-जेनेरिक डेल्फी का अवशेष है। इस तरह के कच्चे टाइपलेस तंत्र का उपयोग करने के लिए आजकल यह समझ में नहीं आता है। सामान्य 'TList ' इस तकनीक को पीछे छोड़ देता है। –

+0

@ डेविड हेफरन प्राचीन है, लेकिन उपयोगकर्ताओं के लिए उपयोगी है जो डेल्फी (> = 200 9) के नए संस्करणों तक पहुंच के बिना उपयोगी है। इसके अलावा ओपी डेल्फी संस्करण निर्दिष्ट नहीं करता है जो उपयोग कर रहा है। – RRUZ

+1

@RRUZ बिल्कुल।इसे प्री-जेनरिक का प्रयोग करें, लेकिन इससे आगे बढ़ने के बाद कृपया इसे रोक दें। –

उत्तर

5

AddObject विधि आपको आइटम संपत्ति में संग्रहीत स्ट्रिंग से जुड़े एक टॉब्जेक्ट पता (सूचक) को स्टोर करने देता है। Objects संपत्ति संग्रहीत वस्तुओं तक पहुंच के लिए है।

इस सरल नमूना को जांचें जो प्रत्येक स्ट्रिंग से जुड़े एक पूर्णांक मान को संग्रहीत करने के लिए AddObject का उपयोग करता है।

var 
List : TStringList; 
I : integer; 
begin 
    try 
    List:=TStringList.Create; 
    try 
     List.AddObject('Item 1', TObject(332)); 
     List.AddObject('Item 2', TObject(345)); 
     List.AddObject('Item 3', TObject(644)); 
     List.AddObject('Item 4', TObject(894)); 

     for I := 0 to List.Count-1 do 
     Writeln(Format('The item %d contains the string "%s" and the integer value %d',[I, List[I], Integer(List.Objects[i])])); 
    finally 
     List.Free; 
    end; 
    except 
    on E: Exception do 
     Writeln(E.ClassName, ': ', E.Message); 
    end; 
    Readln; 
end. 
+1

हां, TStringList.Objects [] मूल्यों को संग्रहीत करने के लिए उपयोग किया जा सकता है। लेकिन याद रखें कि XE2 के साथ सूचक आकार हमेशा पूर्णांक आकार के बराबर नहीं है! –

+1

वास्तव में, लेकिन यदि आप x64 का उपयोग करते हैं तो सूचक 8 बाइट आकार होता है और पूरी तरह से एक पूर्णांक धारण कर सकता है जो हमेशा 4 बाइट आकार का होता है। – RRUZ

+1

यदि आप TStringList के पास 'स्वामित्व ऑब्जेक्ट्स' प्रॉपर्टी (और कन्स्ट्रक्टर पैरामीटर) से पहले डेल्फी का उपयोग कर रहे हैं और आप केवल मूल्यों को संग्रहित नहीं कर रहे हैं लेकिन उदाहरण संदर्भ हैं, तो आपको स्ट्रिंगलिस्ट को मुक्त करने से पहले उन ऑब्जेक्ट संदर्भों में आपके द्वारा रखे गए किसी भी उदाहरण को मुक्त करना होगा (जब तक कि निश्चित रूप से उन उदाहरणों का स्वामित्व कुछ अन्य नहीं था)। –

2

TStringList तारों की एक सूची से अधिक है।

यह नाम मूल्य जोड़े के लिए इस्तेमाल किया जा सकता:

stringlist.Values['apple'] := 'one'; 
stringlist.Values['banana'] := 'two'; 

लेकिन यह भी किसी भी वस्तु (या किसी भी सूचक) के साथ तार संबद्ध करने के लिए इस्तेमाल किया जा सकता।

stringlist.AddObject('apple', TFruit.Create); 
stringlist.AddObject('banana', TFruit.Create); 


i := stringlist.IndexOf('apple'); 
if i >= 0 then 
    myfruit := stringlist.Objects[i] as TFruit; 

टीएलिस्ट एक सूची है जो पॉइंटर्स स्टोर करती है। वे तारों से जुड़े नहीं हैं।

+3

-1 आप * अपने उत्तर में उल्लेख करेंगे कि किसी भी आवंटित ऑब्जेक्ट ('TFuit.Create') को जारी किया जाना चाहिए (' i: = 0 के लिए stringlist.Count-1 stringList.Objects [i] फ़्री; 'या 'Own ऑब्जेक्ट्स' प्रॉपर्टी) - केवल बनाई गई वस्तुओं को स्टोर करने के लिए 'TStringList' का उपयोग करना एक अच्छा विचार नहीं है। आप इसे उन ऑब्जेक्ट्स के साथ उपयोग कर सकते हैं जिनमें वीसीएल-प्रबंधित स्वामित्व है या उनके पास जीवन भर है। ओपी अप्रत्याशित प्रतीत होता है, इसलिए आपके उत्तर में कम से कम उल्लेख करना चाहिए (जैसे केन व्हाइट की)। –

16

यह आइटमों की एक जोड़ी जोड़ता है: TStringList.Strings सूची में एक प्रविष्टि, और TStringList.Objects सूची में TObject से मेल खाता है।

यह आपको उदाहरण के लिए, स्ट्रिंग्स की एक सूची संग्रहीत करने की अनुमति देता है जो आइटम के लिए नाम प्रदान करते हैं, और एक ऑब्जेक्ट जो मेल खाने वाला आइटम है।

type 
    TPerson=class 
    FFirstName, FLastName: string; 
    FDOB: TDateTime; 
    FID: Integer; 
    private 
    function GetDOBAsString: string; 
    function GetFullName: string; 
    published 
    property FirstName: string read FFirstName write FFirstName; 
    property LastName: string read FLastName write FLastName; 
    property DOB: TDateTime read FDOB write FDOB; 
    property DOBString: string read GetDOBAsString; 
    property FullName: string read GetFullName; 
    property ID: Integer read FID write FID; 
    end; 

implementation 

{TPerson} 
function TPerson.GetDOBAsString: string; 
begin 
    Result := 'Unknown'; 
    if FDOB <> 0 then 
    Result := DateToStr(FDOB); 
end; 

function TPerson.GetFullName: string; 
begin 
    Result := FFirstName + ' ' + FLastName; // Or FLastName + ', ' + FFirstName 
end; 

var 
    PersonList: TStringList; 
    Person: TPerson; 
    i: Integer; 
begin 
    PersonList := TStringList.Create; 
    try 
    for i := 0 to 9 do 
    begin 
     Person := TPerson.Create; 
     Person.FirstName := 'John'; 
     Person.LastName := Format('Smith-%d', [i]); // Obviously, 'Smith-1' isn't a common last name. 
     Person.DOB := Date() - RandRange(1500, 3000); // Make up a date of birth 
     Person.ID := i; 
     PersonList.AddObject(Person.LastName, Person); 
    end; 

    // Find 'Smith-06' 
    i := PersonList.IndexOf('Smith-06'); 
    if i > -1 then 
    begin 
     Person := TPerson(PersonList[i]); 
     ShowMessage(Format('Full Name: %s, ID: %d, DOB: %s', 
         [Person.FullName, Person.ID, Person.DOBString])); 
    end; 
    finally 
    for i := 0 to PersonList.Count - 1 do 
     PersonList.Objects[i].Free; 
    PersonList.Free; 
    end; 

यह स्पष्ट रूप से एक प्रदूषित उदाहरण है, क्योंकि ऐसा कुछ नहीं है जिसे आप वास्तव में उपयोगी पाते हैं। यह अवधारणा को प्रदर्शित करता है, यद्यपि।

एक और आसान उपयोग स्ट्रिंग के साथ एक पूर्णांक मूल्य को संग्रहीत करने के लिए है (उदाहरण के लिए, TComboBox या TListBox में आइटमों की एक सूची दिखा रहा है और डेटाबेस क्वेरी में उपयोग के लिए संबंधित आईडी)। इस मामले में, आपको केवल Objects सरणी में पूर्णांक टाइप करना होगा (या कुछ और जो आकारऑफ (सूचक) है)।

// Assuming LBox is a TListBox on a form: 
while not QryItems.Eof do 
begin 
    LBox.Items.AddObject(QryItem.Fields[0].AsString, TObject(QryItem.Fields[1[.AsInteger)); 
    QryItems.Next; 
end; 

// User makes selection from LBox 
i := LBox.ItemIndex; 
if i > -1 then 
begin 
    ID := Integer(LBox.Items.Objects[i]); 
    QryDetails.ParamByName('ItemID').AsInteger := ID; 
    // Open query and get info. 
end; 

एक वास्तविक TObject के अलावा अन्य चीजों के भंडारण के मामले में, आप सामग्री को मुक्त करने की जरूरत नहीं है। चूंकि वे वास्तविक वस्तुएं नहीं हैं, इसलिए TStringList को छोड़कर मुक्त करने के लिए कुछ भी नहीं है।

+2

नए डेल्फी संस्करणों में TbjectList की तरह 'Ownssbjects' प्रॉपर्टी (और कन्स्ट्रक्टर पैरामीटर) के साथ एक TStringList है। यदि यह सत्य पर सेट किया गया है, तो आपको सूची को मुक्त करने से पहले, उदाहरणों को मुक्त नहीं करना चाहिए, आपको इसकी आवश्यकता नहीं है। –

+1

अच्छा बिंदु, मारजन। इसका जिक्र करने के लिए धन्यवाद। :) –

+0

यह वर्णन करना सहायक होगा कि ऑब्जेक्ट्स के साथ क्या होता है जब उदाहरण के लिए 'stringListB: = stringListA'। क्या stringListB.Objects पॉइंटर की मूल प्रतिलिपि में एक प्रतिलिपि लेते हैं? क्या इसका मतलब यह है कि जब हम चाहते हैं कि 'stringListA' मुक्त हो, तो हमें किसी एक को अपने निर्दिष्ट ऑब्जेक्ट्स को मुक्त नहीं करना चाहिए? – Vassilis

संबंधित मुद्दे