2012-11-21 22 views
6

रीज़ा द्वारा धागे के बाद मेरे दिमाग में उठाया गया प्रश्न।सूची <T> और सरणी अनुक्रमणिका के बीच क्या अंतर है?

तो, पर विचार निम्नलिखित struct और interface (definetely बहुत उपयोगी नहीं है, लेकिन सिर्फ इस मुद्दे को दिखाने के लिए):

public interface IChangeStruct 
{ 
    int Value { get; } 
    void Change(int value); 
} 

public struct MyStruct : IChangeStruct 
{ 
    int value; 

    public MyStruct(int _value) 
    { 
     value = _value; 
    } 

    public int Value 
    { 
     get 
     { 
      return value; 
     } 
    } 

    public void Change(int value) 
    { 
     this.value = value; 
    } 
} 

MyStructIChangeStruct लागू करता है, तो हम सही ढेर में इसके बारे में एक बॉक्स्ड प्रति बदल सकते हैं अनबॉक्सिंग के बिना और एक नए के साथ बदलना। यह निम्नलिखित कोड के साथ demostrated जा सकता है:

List<MyStruct> l2 = new List<MyStruct> 
{ 
    new MyStruct(0) 
}; 

Console.WriteLine(l2[0].Value); //0 
l2[0].Change(10); 
Console.WriteLine(l2[0].Value); //also 0 

जहां तक ​​मैं समझ गया, पहले मामले l1[0] में बॉक्सिंग के लिए referense लौटे:

MyStruct[] l1 = new MyStruct[] 
{ 
    new MyStruct(0) 
}; 

Console.WriteLine(l1[0].Value); //0 
l1[0].Change(10); 
Console.WriteLine(l1[0].Value); //10 

अब, चलो List<T> को सरणी बदलने के लिए, यानी जाने संरचना, जबकि दूसरे में - यह और बाकी था।

मैं भी इस एकत्रित न करने की कोशिश की और पाया:

1) MyStruct[] के लिए:

IL_0030: ldelema Utils.MyStruct 
IL_0035: ldc.i4.s 10 
IL_0037: call  instance void Utils.MyStruct::Change(int32) 

2) List<MyStruct> के लिए:

IL_007c: callvirt instance !0 class [mscorlib]System.Collections.Generic.List`1<valuetype Utils.MyStruct>::get_Item(int32) 
IL_0081: stloc.s CS$0$0001 
IL_0083: ldloca.s CS$0$0001 
IL_0085: ldc.i4.s 10 
IL_0087: call  instance void Utils.MyStruct::Change(int32) 

लेकिन मैं होने के कारण इसे अच्छी तरह से समझने के लिए तैयार नहीं है।

तो, List<T> वापस क्या हुआ? या इंडेक्स द्वारा सरणी और List<T> वापसी तत्व कैसे करते हैं? या यह केवल मूल्य प्रकार के साथ मामला है और संदर्भ प्रकारों से कोई लेना देना नहीं है?

पी.एस .: मैं समझते हैं कि एक नहीं करना चाहिए परिवर्तन एक मान प्रकार उदाहरण है, लेकिन वर्णित मुद्दा मुझे समझने बना कर , मैं कभी पता चला कि List<T> और सरणी काम करते हैं।

उत्तर

9

नेट ldelema निर्देश (सरणी तत्व का लोड पता) का उपयोग करके सरणी तत्वों को जगह में संबोधित कर सकता है।

यह आपको कॉपी किए बिना सरणी तत्वों पर सीधे संचालन करने की अनुमति देता है। (यही कारण है कि आप ref या out पैरामीटर के रूप में एक सरणी तत्व पास कर सकते हैं)

List<T> की ऐसी कोई क्षमता नहीं है। इसके बजाय, list[i]list.get_Item(i) के लिए सिंटैक्टिक चीनी है, जो एक सामान्य विधि कॉल है जो संरचना की एक प्रति देता है।

+1

Arrays केवल तब ही क्षमता है जब 0 अनुक्रमित और एकल आयामी सही है? (चूंकि 'ldelema' केवल उन प्रतिबंधों के तहत काम कर सकता है) – Earlz

3

किसी सरणी का सूचकांक निम्न कोड को ref पैरामीटर के रूप में पास करने के समान तरीके से उपलब्ध तत्व बनाता है। किसी अन्य प्रकार के व्यवहार के लिए किसी अन्य प्रकार के लिए कोई भी तंत्र मौजूद नहीं है। कोई भी अन्य प्रकार जो अनुक्रमित पहुंच को विधियों की एक जोड़ी का खुलासा करने की अनुमति देता है, जिसमें से एक कॉलर के कोड में उपलब्ध आंतरिक रूप से संग्रहीत डेटा की प्रतिलिपि बनाता है, और इनमें से एक, कॉलर के कोड, स्टोर से कुछ डेटा की प्रतिलिपि देता है कुछ फैशन में वह डेटा।यह सीमा मूल्य प्रकारों के साथ सबसे अधिक दिखाई दे रही है, लेकिन कुछ मामलों में भी संदर्भ प्रकारों के साथ समस्याग्रस्त हो सकता है (उदाहरण के लिए T[] में किसी तत्व पर Interlocked.ComapreExchange निष्पादित करना संभव है, लेकिन List<T> वाले तत्व पर नहीं)।

यदि कोई व्यक्ति अपने स्वयं के संग्रह प्रकार तैयार कर रहा है, तो कोई ActOnItem सदस्य की पेशकश करके इंडेक्सरों पर सीमा को कम कर सकता है, इस प्रकार MyFancyList.ActOnItem(4, (ref Point it) => {it.X += 4;}); जैसे कोड की अनुमति देता है। यह अलग-अलग ref पैरामीटर के साथ जेनेरिक संस्करणों के परिवार को प्रदान करने में मददगार हो सकता है जो कॉलर (उदा। MyFancyList.ActOnItem(4, (ref MyThing it, ref Thing newValue, ref Thing compareValue) => Threading.Interlocked.CompareExchange(ref it, newValue, compareValue);) के माध्यम से पारित किया जाएगा क्योंकि इस तरह के तरीकों के उपयोग से लैम्बडा को कैप्चर किए गए चर का उपयोग करने की आवश्यकता से बचा जा सकता है।