2009-03-25 6 views
19

में सरणी लंबाई कैसे सेट करें मैं अभी भी सी # के लिए नया हूं और मैं सरणी पर विभिन्न मुद्दों के साथ संघर्ष कर रहा हूं। मुझे मेटाडेटा ऑब्जेक्ट्स (नाम मूल्य जोड़े) की एक सरणी मिली है और मैं जानना चाहता हूं कि केवल "इनपुटप्रॉपर्टी" ऑब्जेक्ट्स की संख्या को कैसे बनाना है, जिसकी मुझे वास्तव में आवश्यकता है। इस लूप में मैंने मनमाने ढंग से तत्वों की संख्या 20 पर सेट की है और जब प्रविष्टि शून्य हो जाती है तो मैं जमानत देने का प्रयास करता हूं लेकिन इसके प्राप्त होने वाले वेब सेवा को किसी भी शून्य तत्व को पास नहीं किया जाता है:सी # गतिशील रूप से

private Update BuildMetaData(MetaData[] nvPairs) 
{ 
    Update update = new Update(); 
    InputProperty[] ip = new InputProperty[20]; // how to make this "dynamic" 
    int i; 
    for (i = 0; i < nvPairs.Length; i++) 
    { 
     if (nvPairs[i] == null) break; 
     ip[i] = new InputProperty(); 
     ip[i].Name = "udf:" + nvPairs[i].Name; 
     ip[i].Val = nvPairs[i].Value; 
    } 
    update.Items = ip; 
    return update; 
} 

संक्षेप में, कहें कि मेरे पास उपर्युक्त इनपुट सरणी में केवल 3 नाम जोड़े हैं? आईपी ​​नामक सरणी के लिए 20 तत्व आवंटित करने के बजाय, यह इतना आईपी कैसे कोड कर सकता है जितना बड़ा होना चाहिए। अद्यतन ऑब्जेक्ट किसी अन्य webservice पर पारित किया गया है, इसलिए क्रमबद्धता महत्वपूर्ण है (यानी मैं namevaluecollection, आदि का उपयोग नहीं कर सकता)।

पेज। "टिप्पणी जोड़ें" सुविधा के माध्यम से पोस्ट किए गए प्रश्न पर अनुवर्ती करने का एकमात्र तरीका है?

उत्तर

20

आप एक List, ArrayList, या अन्य गतिशील आकार संग्रह का उपयोग नहीं करना चाहते हैं और उसके बाद में कन्वर्ट एक सरणी (जिस तरीके से मैं अनुशंसा करता हूं, वैसे ही), तो आपको सरणी को अपने अधिकतम संभव आकार में आवंटित करना होगा, इस पर ध्यान रखें कि आपने कितनी वस्तुओं को रखा है, और उसके बाद एक नया सरणी बनाएं इसमें वे आइटम:

private Update BuildMetaData(MetaData[] nvPairs) 
{ 
    Update update = new Update(); 
    InputProperty[] ip = new InputProperty[20]; // how to make this "dynamic" 
    int i; 
    for (i = 0; i < nvPairs.Length; i++) 
    { 
     if (nvPairs[i] == null) break; 
     ip[i] = new InputProperty(); 
     ip[i].Name = "udf:" + nvPairs[i].Name; 
     ip[i].Val = nvPairs[i].Value; 
    } 
    if (i < nvPairs.Length) 
    { 
     // Create new, smaller, array to hold the items we processed. 
     update.Items = new InputProperty[i]; 
     Array.Copy(ip, update.Items, i); 
    } 
    else 
    { 
     update.Items = ip; 
    } 
    return update; 
} 

वैकल्पिक विधि हमेशा update.Items = ip; आवंटित करने के लिए और उसके बाद का आकार परिवर्तन आवश्यक हो तो होगा:

update.Items = ip; 
if (i < nvPairs.Length) 
{ 
    Array.Resize(update.Items, i); 
} 

यह कम कोड है, लेकिन संभावना है काम का एक ही राशि कर खत्म हो जाएगा (अर्थात एक नई सरणी बनाना और पुरानी वस्तुओं की प्रतिलिपि बनाना)।

27
InputProperty[] ip = new InputProperty[nvPairs.Length]; 

या, आप तो जैसे एक सूची का उपयोग कर सकते हैं: में सी # आप सही अंदर पाश के लिए एक में अपने पूर्णांक चर उपयोग delcare कर सकते हैं

List<InputProperty> list = new List<InputProperty>(); 
InputProperty ip = new (..); 
list.Add(ip); 
update.items = list.ToArray(); 

एक और बात मैं करना चाहते हैं इंगित करने के लिए, पाश:

for(int i = 0; i<nvPairs.Length;i++ 
{ 
. 
. 
} 

और सिर्फ इसलिए कि मैं मूड में हूँ, यहाँ इस विधि IMO करने के लिए एक क्लीनर तरीका है:

private Update BuildMetaData(MetaData[] nvPairs) 
{ 
     Update update = new Update(); 
     var ip = new List<InputProperty>(); 

     foreach(var nvPair in nvPairs) 
     { 
      if (nvPair == null) break; 
      var inputProp = new InputProperty 
      { 
       Name = "udf:" + nvPair.Name, 
       Val = nvPair.Value 
      }; 
      ip.Add(inputProp); 
     } 
     update.Items = ip.ToArray(); 
     return update; 
} 
+0

मुझे लगता है कि तुम यहाँ समस्या वंचित हो रहे हैं - इनपुट सरणी, nvPairs, उपयोगी लोगों के बाद रिक्त मान हैं। बस इसकी लंबाई का उपयोग कुछ भी हल नहीं होगा। – Whatsit

+0

ओपी ने कभी निर्दिष्ट नहीं किया है। मैंने अभी सोचा कि अगर नल एक सरल सैनिटी चेक था। यदि आप जो कह रहे हैं वह वास्तव में मामला है, तो आप सही हैं। सूची निश्चित रूप से जाने का रास्ता होगा। – BFree

+0

हम्म मैंने नहीं सोचा कि यह एक सैनिटी चेक हो सकता है। यह निश्चित रूप से संभव है। – Whatsit

5

क्या एक सरणी होने की आवश्यकता है? यदि आप सी # में उपलब्ध एक ऐरेलिस्ट या अन्य ऑब्जेक्ट्स में से एक का उपयोग करते हैं, तो आपके पास सामग्री के साथ यह सीमा नहीं होगी। हैशटेबल, पहचान पत्र, आईएलआईस्ट, आदि .. सभी तत्वों की एक गतिशील संख्या की अनुमति देते हैं।

+0

मैं सहमत हूं। यदि आपको किसी सरणी की कार्यक्षमता की आवश्यकता है और गतिशील लंबाई है, एक ArrayList सबसे सरल और स्पष्ट उत्तर है। – TheTXI

+0

ऐरेलिस्ट? क्या हम जेनेरिक के लिए एलर्जी हैं? –

+0

michl86 टिप्पणियां सूची का उपयोग और अंत में .ToArray बहुत धीमी है। ऐसा लगता है कि ArrayList को उसी तरह सरणी में परिवर्तित किया जा सकता है। मेरे अंतिम परिणाम के लिए मुझे एक सरणी की आवश्यकता नहीं है जो ArrayList नहीं है। क्या प्रदर्शन खराब है। ToArray() बस वापस आने से पहले? –

2

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

private Update BuildMetaData(MetaData[] nvPairs) 
    { 
     Update update = new Update(); 
     List<InputProperty> ip = new List<InputProperty>(); 
     for (int i = 0; i < nvPairs.Length; i++) 
     { 
      if (nvPairs[i] == null) break; 
      ip[i] = new InputProperty(); 
      ip[i].Name = "udf:" + nvPairs[i].Name; 
      ip[i].Val = nvPairs[i].Value; 
     } 
     update.Items = ip.ToArray(); 
     return update; 
    } 
+0

ऊपर अनुकूलित कोड। "टाइप या नेमस्पेस नाम 'सूची' प्राप्त नहीं हो सका (क्या आप एक प्रयोग निर्देश या असेंबली संदर्भ खो रहे हैं?) मेरे पास यह भी है (वह और क्या चाहता है): सिस्टम का उपयोग कर। चयन; सिस्टम का उपयोग कर .Collections.Generic; सिस्टम का उपयोग कर। चयन। –

+0

कोई बात नहीं ... इसे अभी मिला। –

2

या सी # में 3.0 System.Linq का उपयोग कर आप मध्यवर्ती सूची को छोड़ सकते हैं:

private Update BuildMetaData(MetaData[] nvPairs) 
{ 
     Update update = new Update(); 
     var ip = from nv in nvPairs 
       select new InputProperty() 
       { 
        Name = "udf:" + nv.Name, 
        Val = nv.Value 
       }; 
     update.Items = ip.ToArray(); 
     return update; 
} 
+0

आप यह जांचना भूल जाते हैं कि एनवी शून्य है –

0

आम तौर पर, सरणी को उनके आकार को आरंभ करने के लिए स्थिरांक की आवश्यकता होती है। आप लंबाई प्राप्त करने के लिए एक बार एनवीपीयर से अधिक हो सकते हैं, फिर "गतिशील रूप से" इस तरह की लंबाई के लिए एक चर का उपयोग कर एक सरणी बनाते हैं।

InputProperty[] ip = (InputProperty[])Array.CreateInstance(typeof(InputProperty), length); 

हालांकि, मैं इसकी अनुशंसा नहीं करता हूं।बस

List<InputProperty> ip = ... 
... 
update.Items = ip.ToArray(); 

समाधान के साथ बस रहें। यह इतना कम प्रदर्शन नहीं है, और बेहतर तरीके से दिख रहा है।

4

इस का उपयोग करें:

Array.Resize(ref myArr, myArr.Length + 5); 
1

उपयोग Array.CreateInstance गतिशील एक सरणी बनाने के लिए।

private Update BuildMetaData(MetaData[] nvPairs) 
    { 
     Update update = new Update(); 
     InputProperty[] ip = Array.CreateInstance(typeof(InputProperty), nvPairs.Count()) as InputProperty[]; 
     int i; 
     for (i = 0; i < nvPairs.Length; i++) 
     { 
      if (nvPairs[i] == null) break; 
      ip[i] = new InputProperty(); 
      ip[i].Name = "udf:" + nvPairs[i].Name; 
      ip[i].Val = nvPairs[i].Value; 
     } 
     update.Items = ip; 
     return update; 
    } 
0

आप इस तरह से गतिशील रूप से एक सरणी बना सकते हैं:

static void Main() 
    { 
     // Create a string array 2 elements in length: 
     int arrayLength = 2; 
     Array dynamicArray = Array.CreateInstance(typeof(int), arrayLength); 
     dynamicArray.SetValue(234, 0);        // → a[0] = 234; 
     dynamicArray.SetValue(444, 1);        // → a[1] = 444; 
     int number = (int)dynamicArray.GetValue(0);      // → number = a[0]; 


     int[] cSharpArray = (int[])dynamicArray; 
     int s2 = cSharpArray[0]; 

    }