मुझे पता है कि अगर के बराबर मौजूद चाहते हैं (.net)VB6 बराबर सूची <someclass>
list<somefixedclass>
VB6 में
मुझे पता है कि VB6 में संग्रह मौजूद हैं, लेकिन यह वस्तु (संस्करण) का उपयोग करता है के बजाय एक विशिष्ट वस्तु।
धन्यवाद।
मुझे पता है कि अगर के बराबर मौजूद चाहते हैं (.net)VB6 बराबर सूची <someclass>
list<somefixedclass>
VB6 में
मुझे पता है कि VB6 में संग्रह मौजूद हैं, लेकिन यह वस्तु (संस्करण) का उपयोग करता है के बजाय एक विशिष्ट वस्तु।
धन्यवाद।
VB.NET में पाए गए जेनेरिक List<T>
पर वीबी 6 में कोई प्रत्यक्ष समतुल्य नहीं है। हालांकि, वीबी 6 में Collection
जैसी चीज है, जो समान कार्यक्षमता प्रदान करती है। प्राथमिक अंतर यह है कि एक वीबी 6 Collection
दृढ़ता से टाइप नहीं किया गया, जिसका अर्थ है कि सभी ऑब्जेक्ट संग्रह में Variants
के रूप में संग्रहीत हैं। कुछ मामलों में, यह फायदेमंद हो सकता है, क्योंकि यह आपको एक ही संग्रह में कई अलग-अलग प्रकार के डेटा स्टोर करने की अनुमति देता है, और वास्तव में, वीबी आंतरिक रूप से इस ऑब्जेक्ट का उपयोग करता है। Collection
और अप-कास्ट ऑब्जेक्ट्स का उपयोग करने के लिए पर्याप्त आसान है क्योंकि उन्हें कक्षा से पुनर्प्राप्त किया जाता है, लेकिन आप ऐसा कर सकते हैं। वीबी रनटाइम में दृढ़ता से टाइप किए गए संग्रह को लागू करना संभव नहीं है।
कहा जा रहा है कि, एक ऐसा कामकाज है जिसे आप कार्यान्वित कर सकते हैं। इसी तरह जेनिक्स पेश किए जाने से पहले वीबीएनईटी के प्रारंभिक संस्करणों में संग्रह कैसे लागू किए गए थे, आप कक्षा में Collection
को लपेट सकते हैं, जहां आंतरिक Collection
तक पहुंच केवल उन वर्गों के माध्यम से होती है जिन्हें आप इस कक्षा से एक्सपोज़ करते हैं। इस डिजाइन पैटर्न को आमतौर पर "कस्टम संग्रह" के रूप में जाना जाता है।
इसका स्वचालित रूप से कास्टिंग को संभालने का लाभ होता है, और आपके कोड के उपभोक्ताओं को इस तरह के कार्यान्वयन विवरणों को याद रखने के लिए याद रखने से लाभ होता है। यह (सभी संभावनाओं) की संभावना का ख्याल रखता है कि आप रन-टाइम पर संग्रह के माध्यम से लूपिंग करेंगे, जिसमें केवल एक प्रकार का ऑब्जेक्ट होना चाहिए, लेकिन गलती से एक दूसरा, असंगत प्रकार का ऑब्जेक्ट जोड़ा गया जो आपके कोड का कारण बनता है अपवाद फेंकने के लिए। निस्संदेह, नुकसान यह है कि आपको अपने कस्टम संग्रह पर सार्वजनिक विधियों के रूप में Collection
ऑब्जेक्ट द्वारा पहले से प्रदान की गई अधिकांश कार्यक्षमताओं को फिर से कार्यान्वित करना होगा।
तरीका यहां बताया गया है कि के बारे में जाना हो सकता है की एक उदाहरण है:
Public Class CustomerCollection
''#Internal collection, exposed by this class
Private m_Customers As Collection
Private Sub Class_Initialize()
''#Set up the internal collection
Set m_Customers = New Collection
End Sub
Public Sub Add(ByVal cust as Customer, Optional ByVal key as String)
''#Add the Customer object to the internal collection
If IsMissing(key) Then
m_Customers.Add cust
Else
m_Customers.Add cust, key
End If
End Sub
Public Property Get Count() As Integer
''#Return the number of objects in the internal collection
Count = m_Customers.Count
End Property
Public Sub Remove(ByVal index As Variant)
''#Remove the specified object from the internal collection,
''# either by its index or its key
m_Customers.Remove index
End Sub
Public Function Item(ByVal index As Variant) as Customer
''#Return the specified object from the internal collection,
''# either by its index or its key
Set Item = m_Customers.Item(index)
End Function
Public Sub Clear()
''#Removes all objects from the internal collection
Set m_Customers = New Collection
End Sub
End Class
ध्यान दें कि संग्रह के डिफ़ॉल्ट पद्धति के रूप में कस्टम संग्रह के Item
गुण सेट करने के लिए (जैसे निर्मित Collection
वस्तु), तो आपको जरूरत है क्रम में वीबी 6 IDE में निम्न चरणों का पालन करने के लिए:
"उपकरण" मेनू से, क्लिक करें "प्रक्रिया विशेषता"
"नाम" कॉम्बो बॉक्स से अपनी कस्टम कक्षा का नाम चुनें।
जब संवाद प्रकट होता है, तो "उन्नत" बटन पर क्लिक करें।
"प्रक्रिया आईडी" कॉम्बो बॉक्स में "(डिफ़ॉल्ट)" आइटम का चयन करें।
क्लिक करें "ठीक है"
आप भी For Each
वाक्य रचना (भी तरह निर्मित Collection
वस्तु), आप एक जोड़ सकते हैं का उपयोग कर अपने कस्टम वर्ग की गणना अनुमति देने के लिए करना चाहते हैं तो अपने कस्टम वर्ग के लिए NewEnum
समारोह:
Public Property Get NewEnum() As IUnknown
''#Provides support for enumeration using For Each
Set NewEnum = m_Customers.[_NewEnum]
End Property
कर लेने के बाद, आप इस संपत्ति का उपयोग करने के वीबी को निर्देश देने की जरूरत है:
पहले की तरह, "उपकरण" मेनू
से "प्रक्रिया विशेषता" संवाद खोलने "नाम" कॉम्बो बॉक्स से अपने कस्टम वर्ग के नाम का चयन करें।
जब संवाद प्रकट होता है, तो "उन्नत" बटन पर क्लिक करें।
"प्रक्रिया आईडी" कॉम्बो बॉक्स में "-4" संख्या टाइप करें।
क्लिक करें "ठीक है"
वीबी 6 एक प्राचीन भाषा है। इसमें टेम्पलेट जैसी प्रकार नहीं हैं क्योंकि आधुनिक भाषाओं में हैं (सी ++, सी #, जावा)। तो आपको संग्रह में वेरिएंट के रूप में अपनी ऑब्जेक्ट्स को स्टोर करना होगा और फिर उन्हें बाद में अपने ऑब्जेक्ट प्रकार पर डालना होगा।
मैं आमतौर पर विभिन्न परियोजनाओं में सी # के साथ काम करता हूं लेकिन स्टैंड अकेले निष्पादन योग्य के लिए काम करता हूं। क्यूं कर?। चूंकि .NET धीमा है (ज्यादातर मामलों में), इसे आसानी से हटाया जा सकता है, इसे नेट फ्रेमवर्क की आवश्यकता होती है, यह अधिकांश ओएस के साथ काम नहीं करती है, vb6 विंडोज 95 से लिनक्स तक चल सकता है (बिना किसी प्रयास के शराब के साथ)। और स्टैंड के लिए जावा अकेले निष्पादन योग्य सबसे अच्छा "फंकी" है। मेरा दूसरा विकल्प डेल्फी और सी ++ है लेकिन यह एक और कहानी है। – magallanes
आपकी तर्क गलत है। वीबी 6 में सामान्य प्रकार की कमी नहीं है क्योंकि यह एक प्राचीन भाषा है (जो यह नहीं है, सी ++ बहुत पुराना है), लेकिन क्योंकि इस तरह की जटिलताओं को उस भाषा से दूर रखने का एक सचेत निर्णय था जिसमें पूरी तरह से अलग जगह है। – GSerg
ध्यान दें कि मैंने डाउनवोट नहीं किया है, क्योंकि -2 एक पोस्ट के लिए पर्याप्त कम है जो वास्तव में सही उत्तर प्रदान करता है।लेकिन मुझे लगता है कि यह इंगित करने लायक है कि हम प्रोग्रामर के रूप में हमेशा * जो भी भाषा चाहते हैं उसे चुनने की लक्जरी नहीं होती है। आपका सुझाव वास्तव में सहायक नहीं है, और शायद किसी भी चीज़ से ज्यादा निराशाजनक है। और इसके लायक होने के लिए, आपको "प्राचीन" सी # 1.1 में जेनेरिक से पहले जीवन याद हो सकता है ... –
संपादित करें: यदि कोड़ी ग्रे की समाधान आपकी आवश्यकताओं के लिए भी बड़े है, आप के बजाय इस प्रकार की कोशिश कर सकते "गरीब आदमी का सूची" समाधान,:
Dim l() as somefixedclass
Redim l(0)
'...
'increase size dynamically:
Redim Preserve l(ubound(l)+1)
'...
बेशक
, एक List<somefixedclass>
(सी में #) या एक VB.NET में List(Of somefixedclass)
अधिक "उपयोगकर्ता के अनुकूल" है क्योंकि इसमें खोज, निकालें, AddRange और कुछ अन्य उपयोगी चीजें हैं। पुरानी वीबी 6 निर्माण "खाली सूची" मामले के साथ बहुत बुरी तरह से काम करता है। भूलना नहीं है, < सूचीबद्ध करें ..> बड़ी सूचियों (आकार> 1000) के लिए वृद्धि का बेहतर प्रदर्शन है।
हां, यह एक और विकल्प है, धन्यवाद – magallanes
यह एक व्यावहारिक समाधान है, सिवाय इसके कि 'रेडीम संरक्षित' का प्रदर्शन हत्यारा हो सकता है यदि आप इसे स्वयं बहुत बुलाते हैं। वीबी 6 में सरणी या 'संग्रह' का उपयोग करना एक महत्वपूर्ण डिजाइन निर्णय है, और सबसे अच्छी सलाह यह है कि यदि आप समय से पहले की गई वस्तु की संख्या को जानते हैं (या बारीकी से अनुमान लगा सकते हैं), तो आपको एक सरणी चुननी चाहिए। प्रदर्शन 'संग्रह' से थोड़ा बेहतर है, लेकिन यदि आप गतिशील रूप से वस्तुओं को जोड़ और निकाल देंगे, तो 'संग्रह' शायद सबसे अच्छा विकल्प है। –
@ कोडी ग्रे: हां वास्तव में, प्रदर्शन इस तरह खराब हो सकता है। सबसे वास्तविक दुनिया के कार्यक्रमों में मैंने पिछले 5 वर्षों में एक्सेल-वीबीए में लिखा था, सूची का 98% मामला 500 से कम प्रविष्टियों वाली एक सूची है, जहां यह समाधान पूरी तरह से पर्याप्त है। –
यहाँ ArrayList के हमारे कार्यान्वयन है। आप दृढ़ता से टाइप की गई कक्षा के लिए आधार के रूप में इसका उपयोग कर सकते हैं (स्पष्ट रूप से विरासत के माध्यम से नहीं बल्कि कोडीग्रे के उत्तर में व्यक्त की गई रचना के माध्यम से), लेकिन अगर आपको सुरक्षा की आवश्यकता नहीं है तो यह संग्रह वर्ग से काफी बेहतर है।
Option Explicit
Private mavInternalArray() As Variant
Private mlArraySize As Long
Private mlCount As Long
Private mlGrowSize As Long
Private mfZeroIndex As Boolean
'---------------------------------------------------------------------------------------
' Procedure Clear
'---------------------------------------------------------------------------------------
Public Sub Clear()
Dim index As Long
For index = 0 To mlCount - 1
If IsObject(mavInternalArray(index)) Then
Set mavInternalArray(index) = Nothing
End If
Next index
mlCount = 0
End Sub
'---------------------------------------------------------------------------------------
' Procedure Swap
'---------------------------------------------------------------------------------------
Public Sub Swap(Index1 As Long, index2 As Long)
Dim vTmp As Variant
If IsObject(mavInternalArray(index2)) Then
Set vTmp = mavInternalArray(index2)
Else
vTmp = mavInternalArray(index2)
End If
If IsObject(mavInternalArray(Index1)) Then
Set mavInternalArray(index2) = mavInternalArray(Index1)
Else
mavInternalArray(index2) = mavInternalArray(Index1)
End If
If IsObject(vTmp) Then
Set mavInternalArray(Index1) = vTmp
Else
mavInternalArray(Index1) = vTmp
End If
End Sub
Public Property Get ZeroIndex() As Boolean
ZeroIndex = mfZeroIndex
End Property
Public Property Let ZeroIndex(fZeroIndex As Boolean)
mfZeroIndex = fZeroIndex
End Property
Public Property Get GrowSize() As Long
GrowSize = mlGrowSize
End Property
Public Property Let GrowSize(lNewSize As Long)
Debug.Assert lNewSize > 0
mlGrowSize = lNewSize
End Property
Private Sub Class_Initialize()
mlGrowSize = 50
mlArraySize = mlGrowSize
mfZeroIndex = True
mlCount = 0
ReDim mavInternalArray(0 To mlGrowSize - 1)
End Sub
'---------------------------------------------------------------------------------------
' Procedure Remove
'---------------------------------------------------------------------------------------
Public Sub Remove(index As Long)
Dim index2 As Long
For index2 = index To mlCount - 2
If IsObject(mavInternalArray(index2 + 1)) Then
Set mavInternalArray(index2) = mavInternalArray(index2 + 1)
Else
mavInternalArray(index2) = mavInternalArray(index2 + 1)
End If
Next index2
If mlCount <= 0 Then
Exit Sub
End If
mlCount = mlCount - 1
If IsObject(mavInternalArray(mlCount)) Then
Set mavInternalArray(mlCount) = Nothing
Else
mavInternalArray(mlCount) = False
End If
End Sub
'---------------------------------------------------------------------------------------
' Procedure Items
'---------------------------------------------------------------------------------------
Public Function Items(index As Long) As Variant
If Not mfZeroIndex Then
index = index - 1
End If
If index < mlCount And index >= 0 Then
If IsObject(mavInternalArray(index)) Then
Set Items = mavInternalArray(index)
Else
Items = mavInternalArray(index)
End If
End If
End Function
Public Sub SetItem(index As Long, Item As Variant)
If Not mfZeroIndex Then
index = index - 1
End If
If IsObject(Item) Then
Set mavInternalArray(index) = Item
Else
mavInternalArray(index) = Item
End If
End Sub
'---------------------------------------------------------------------------------------
' Procedure Add
'---------------------------------------------------------------------------------------
Public Function Add(vItem As Variant) As Long
mlCount = mlCount + 1
If mlCount > mlArraySize Then
mlArraySize = mlArraySize + mlGrowSize
ReDim Preserve mavInternalArray(0 To mlArraySize - 1)
End If
If IsObject(vItem) Then
Set mavInternalArray(mlCount - 1) = vItem
Else
mavInternalArray(mlCount - 1) = vItem
End If
Add = mlCount - 1
End Function
'---------------------------------------------------------------------------------------
' Procedure ItemArray
'---------------------------------------------------------------------------------------
Public Function ItemArray() As Variant
Dim vReturnArray As Variant
vReturnArray = mavInternalArray
ReDim Preserve vReturnArray(0 To mlCount - 1)
ItemArray = vReturnArray
End Function
Public Function Count() As Long
Count = mlCount
End Function
'---------------------------------------------------------------------------------------
' Procedure Insert
'---------------------------------------------------------------------------------------
Public Function Insert(index As Long, vItem As Variant) As Long
Dim index2 As Long
'Make sure array is large enough for a new item
mlCount = mlCount + 1
If mlCount > mlArraySize Then
mlArraySize = mlArraySize + mlGrowSize
ReDim Preserve mavInternalArray(0 To mlArraySize - 1)
End If
'Bump all the items with a higher index up one spot
If index >= mlCount - 1 Then
If IsObject(vItem) Then
Set mavInternalArray(mlCount - 1) = vItem
Else
mavInternalArray(mlCount - 1) = vItem
End If
Else
For index2 = mlCount - 1 To index + 1 Step -1
If IsObject(vItem) Then
Set mavInternalArray(index2) = mavInternalArray(index2 - 1)
Else
mavInternalArray(index2) = mavInternalArray(index2 - 1)
End If
Next index2
If IsObject(vItem) Then
Set mavInternalArray(index) = vItem
Else
mavInternalArray(index) = vItem
End If
End If
Insert = mlCount - 1
End Function
Public Sub Clone(ByRef cDestinationDynamicArray As clsDynamicArray)
Dim index As Long
If cDestinationDynamicArray Is Nothing Then
Set cDestinationDynamicArray = New clsDynamicArray
End If
cDestinationDynamicArray.Clear
For index = 0 To mlCount - 1
Call cDestinationDynamicArray.Add(mavInternalArray(index))
Next index
End Sub
Public Property Get NewEnum() As IUnknown
''#Provides support for enumeration using For Each
Set NewEnum = m_Customers.[_NewEnum]
End Property
+1 दिलचस्प समाधान। जिज्ञासा से बाहर: क्या आपने इसे 'संग्रह' वर्ग की तुलना में अतिरिक्त/सम्मिलन के लिए तेजी से बेंचमार्क किया है? या आप किस तरह से मतलब था कि यह बेहतर था? –
यह किस तरह से बेहतर है? संग्रह आपके जानकारियों के बिना गलती से एक शब्दकोश में बदल सकता है। फिर आपकी गिनती 5 कहें, लेकिन आइटम हैं (0,1,4,5,6) जब आप तत्व 3 तक पहुंचने का प्रयास करते हैं और त्रुटि प्राप्त करते हैं तो आपको एक त्रुटि मिलती है। साथ ही, यह तेज़ है यदि आप अपने सरणी के आकार के लिए उपयुक्त होने के लिए ग्रोसाइज सेट करते हैं (हाँ, यह हर बार बढ़ने पर दोगुना होकर खुद को बेहतर बना सकता है लेकिन यह माइक्रो-ऑप्टिमाइज़ेशन है जो अतिरिक्त कोड के लायक नहीं है)। हालांकि इन दिनों (जब यह लिखा गया था कि एक सीपीयू की गति लगभग 200 मेगाहट्र्ज थी) दक्षता महत्वपूर्ण नहीं है, बग नहीं है। –
+1। IMHO यह (सही) समाधान कई मामलों में सहायक होता है, लेकिन कुछ अन्य मामलों के लिए यह थोड़ा अधिक oversized हो सकता है। –
@ डॉक्टर ब्राउन: सहमत। शब्दों की उत्कृष्ट पसंद। –
+1 लेकिन बॉयलरप्लेट स्वयं को न बनाएं। फ्रांसेस्को बालेना ने लिखा [संग्रह क्लासमास्टर] (http://www.angryhacker.com/download/colclassmaster.zip), वीबी 6 आईडीई के लिए एक मुफ्त प्लग-इन जो आपके लिए स्वचालित रूप से करेगा। यह अब कृपया [AngryHacker] द्वारा होस्ट किया गया है (http://angryhacker.com/blog/archive/2008/05/01/vb6-swiss-army-knife.aspx)) – MarkJ