c# - संग्रह<टी> बनाम सूची<टी> आप अपने इंटरफेस पर क्या उपयोग करना चाहिए?




.net collections (6)

कोड नीचे जैसा दिखता है:

namespace Test
{
    public interface IMyClass
    {
        List<IMyClass> GetList();
    }

    public class MyClass : IMyClass
    {
        public List<IMyClass> GetList()
        {
            return new List<IMyClass>();
        }
    }
}

जब मैं कोड विश्लेषण चलाता हूं तो मुझे निम्नलिखित अनुशंसा मिलती है।

चेतावनी 3 CA1002: माइक्रोसॉफ्ट। डिज़ाइन: संग्रह, ReadOnlyCollection या KeyedCollection का उपयोग करने के लिए 'IMyClass.GetList ()' में 'सूची' बदलें

मुझे इसे कैसे ठीक करना चाहिए और यहां अच्छा अभ्यास क्या है?


इस तरह के मामले में मैं आम तौर पर आवश्यक कम से कम कार्यान्वयन का खुलासा करने की कोशिश करता हूं। यदि उपभोक्ताओं को यह जानने की आवश्यकता नहीं है कि आप वास्तव में एक सूची का उपयोग कर रहे हैं तो आपको एक सूची वापस करने की आवश्यकता नहीं है। माइक्रोसॉफ्ट के रूप में लौटने से एक संग्रह का सुझाव मिलता है कि आप इस तथ्य को छुपाते हैं कि आप अपनी कक्षा के उपभोक्ताओं से एक सूची का उपयोग कर रहे हैं और उन्हें आंतरिक परिवर्तन के खिलाफ अलग कर रहे हैं।


एक उद्देश्य कोड / डिजाइन को अधिक लचीला और एक्स्टेंसिबल बनाना है!


प्रश्न के "क्यों" भाग का जवाब देने के लिए क्यों नहीं List<T> , भविष्य के सबूत और एपीआई सादगी के कारण हैं।

भविष्य-प्रूफिंग

List<T> इसे उप-वर्गीकरण द्वारा आसानी से एक्स्टेंसिबल होने के लिए डिज़ाइन नहीं किया गया है; यह आंतरिक कार्यान्वयन के लिए तेज़ होने के लिए डिज़ाइन किया गया है। आप देखेंगे कि इस पर विधियां वर्चुअल नहीं हैं और इसलिए ओवरराइड नहीं किया जा सकता है, और इसमें Add / Insert / Remove ऑपरेशन में कोई हुक नहीं है।

इसका अर्थ यह है कि यदि आपको भविष्य में संग्रह के व्यवहार को बदलने की आवश्यकता है (उदाहरण के लिए लोगों को जोड़ने की कोशिश की जाने वाली नल ऑब्जेक्ट्स को अस्वीकार करने के लिए, या जब ऐसा होता है तो ऐसा होता है जैसे कि आपकी कक्षा स्थिति को अपडेट करना) तो आपको उस प्रकार को बदलना होगा संग्रह का आप एक पर वापस लौट सकते हैं, जो आप सबक्लास कर सकते हैं, जो एक ब्रेकिंग इंटरफ़ेस परिवर्तन होगा (निश्चित रूप से चीजों की अर्थशास्त्र को बदलना जैसे नल की अनुमति नहीं देना एक इंटरफ़ेस परिवर्तन भी हो सकता है, लेकिन आपकी आंतरिक कक्षा स्थिति को अपडेट करने जैसी चीजें नहीं होंगी)।

तो या तो एक वर्ग लौटने से जिसे आसानी से वर्गीकृत किया जा सकता है जैसे Collection<T> या IList<T> , ICollection<T> या IEnumerable<T> जैसे इंटरफ़ेस को आसानी से उप-वर्गीकृत किया जा सकता है, आप अपने आंतरिक कार्यान्वयन को पूरा करने के लिए एक अलग संग्रह प्रकार के रूप में बदल सकते हैं उपभोक्ताओं के कोड को तोड़ने के बिना आपकी जरूरतें, क्योंकि इसे अभी भी उस प्रकार के रूप में वापस किया जा सकता है, जिसकी वे उम्मीद कर रहे हैं।

एपीआई सरलता

List<T> में कई उपयोगी संचालन शामिल हैं जैसे कि BinarySearch , Sort और इसी तरह। हालांकि यदि यह एक संग्रह है जिसे आप उजागर कर रहे हैं तो संभव है कि आप सूची के अर्थशास्त्र को नियंत्रित करें, न कि उपभोक्ताओं को। इसलिए जब आपकी कक्षा को आंतरिक रूप से इन परिचालनों की आवश्यकता हो सकती है, तो यह बहुत संभावना नहीं है कि आपकी कक्षा के उपभोक्ता उन्हें कॉल करना चाहते हैं (या यहां तक ​​कि उन्हें भी करना चाहिए)।

इस प्रकार, एक सरल संग्रह वर्ग या इंटरफेस की पेशकश करके, आप उन सदस्यों की संख्या को कम करते हैं जो आपके एपीआई के उपयोगकर्ता देखते हैं, और उनके लिए उपयोग करना आसान बनाते हैं।


मुझे कुछ वापस लौटने में कोई समस्या नहीं दिख रही है

this.InternalData.Filter(crteria).ToList();

अगर मैंने आंतरिक डेटा की डिस्कनेक्ट की गई प्रतिलिपि या डेटा क्वेरी के पृथक परिणाम को वापस कर दिया - मैं किसी भी कार्यान्वयन विवरण को बेनकाब किए बिना List<TItem> सुरक्षित रूप से वापस कर सकता हूं, और सुविधाजनक तरीके से लौटाए गए डेटा का उपयोग करने की अनुमति देता List<TItem>

लेकिन यह इस बात पर निर्भर करता है कि मैं किस प्रकार के उपभोक्ता की अपेक्षा करता हूं - यदि यह डेटा ग्रिड जैसा कुछ है, तो मैं IEnumerable<TItem> वापस लौटना पसंद करता हूं जो कि ज्यादातर मामलों में वैसे भी आइटम की कॉपी की गई सूची होगी :)


मैं व्यक्तिगत रूप से एक ठोस संग्रह के बजाय एक इंटरफ़ेस वापस करने के लिए घोषणा करता हूं। यदि आप वास्तव में सूची पहुंच चाहते हैं, तो IList<T> उपयोग करें। अन्यथा, ICollection<T> और IEnumerable<T>


यह सूची वस्तु को सीधे छेड़छाड़ करने के बजाय अपने स्वयं के कार्यान्वयन को दूर करने के बारे में है।

अन्य वस्तुओं (या लोगों) को सीधे अपनी वस्तुओं की स्थिति को संशोधित करने के लिए यह अच्छा अभ्यास नहीं है। संपत्ति गेटर्स / सेटर्स सोचो।

संग्रह -> सामान्य संग्रह के लिए
ReadOnlyCollection -> संग्रहों के लिए जिन्हें संशोधित नहीं किया जाना चाहिए
KeyedCollection -> जब आप इसके बजाय शब्दकोश चाहते हैं।

इसे कैसे ठीक किया जाए इस पर निर्भर करता है कि आप अपनी कक्षा को क्या करना चाहते हैं और GetList () विधि का उद्देश्य। क्या आप विस्तार से समझा सकते हैं?







code-analysis