यदि मैं कक्षा की संपत्ति के रूप में IEnumerable<T>
का पर्दाफाश करता हूं, तो क्या कोई संभावना है कि इसे कक्षा के उपयोगकर्ताओं द्वारा उत्परिवर्तित किया जा सके, और यदि ऐसा है तो उत्परिवर्तन के खिलाफ सुरक्षा का सबसे अच्छा तरीका क्या है, जबकि उजागर संपत्ति के प्रकार IEnumerable<T>
?क्या संपत्ति में एक आईनेमरेबल का पर्दाफाश करना सुरक्षित है?
उत्तर
यह आपके द्वारा लौटने पर निर्भर करता है। यदि आप एक म्यूटेबल List<string>
लौटते हैं (कहें) तो ग्राहक वास्तव में इसे List<string>
पर वापस ला सकता है और इसे बदल सकता है।
आप अपने डेटा की रक्षा कैसे करते हैं इस पर निर्भर करता है कि आपको किसके साथ शुरुआत करना है। ReadOnlyCollection<T>
एक अच्छा रैपर वर्ग है, मानते हुए कि आपको IList<T>
से शुरू करने के लिए मिला है।
public IEnumerable<string> Names
{
get { return names.Select(x => x); }
}
जो प्रभावी रूप से एक iterator में संग्रह लपेटता:
अपने ग्राहकों IList<T>
या ICollection<T>
को लागू करने वापसी मान से लाभ नहीं होगा, तो आप हमेशा की तरह कुछ कर सकता है। (स्रोत को छिपाने के लिए LINQ का उपयोग करने के कई अलग-अलग तरीके हैं ... हालांकि यह दस्तावेज नहीं है कि कौन से ऑपरेटर स्रोत को छुपाते हैं और जो नहीं करते हैं। उदाहरण के लिए Skip(0)
माइक्रोसॉफ्ट कार्यान्वयन में स्रोत को छुपाता है, लेकिन यह नहीं है ऐसा करने के लिए प्रलेखित।)
Select
निश्चित रूप से हालांकि स्रोत को छुपाएं।
सामान्य रूप से, जॉन स्कीट एक अच्छा जवाब प्रदान करता है। मुझे बस इतना जोड़ना होगा कि विभिन्न डेटा संग्रह प्रकारों का उपयोग कार्यक्रमों में सुरक्षा के लिए नहीं किया जाना चाहिए। अगर हम पूर्ण विश्वास वातावरण में भाग लेते हैं, तो कोई भी अंदर छिपा हुआ कुछ भी ढूंढने के लिए हमेशा हमारी वस्तुओं में गहरी खुदाई कर सकता है। अगर हमें वास्तव में परिवर्तनों से संग्रहों की रक्षा करने की आवश्यकता है तो हमें एप्लिकेशन सुरक्षा तंत्र का उपयोग करने की आवश्यकता है। –
संग्रह को मूल प्रकार में वापस लाया जा सकता है और यदि यह उत्परिवर्तनीय है तो इसे फिर से परिवर्तित किया जा सकता है।
मूल रूप से उत्परिवर्तित होने की संभावना से बचने का एक तरीका है सूची सूची की प्रतिलिपि कर रहा है।
एक क्लोन बनाना एक संभावित तरीका है, है, लेकिन क्या वास्तव में यह "सबसे अच्छा तरीका" है? शायद कभी-कभी यह होता है, लेकिन कभी-कभी नहीं। –
एक प्रतिलिपि बड़ी संग्रह के लिए महंगा है। जब तक मुझे वास्तव में एक प्रतिलिपि के अर्थशास्त्र की आवश्यकता नहीं होती है, मैं जॉनस्केट जैसे रैपर पसंद करता हूं। – CodesInChaos
@ एएल, @CodeInChaos - उचित अंक ... उत्तर संशोधित। – Oded
उपयोगकर्ता संग्रह कक्षा में वापस लौटने में सक्षम हो सकता है, इसलिए खुलासा करें।
collection.Select(x => x)
और इस मिल जाएगा एक नया IEnumerable बनाया कि संग्रह
मुझे यह पसंद है। समझें कि यदि संग्रह एक संदर्भ प्रकार है, तो तत्वों के सदस्य अभी भी म्यूटेबल होंगे, हालांकि सूची या सरणी में इसे घुमाने के द्वारा गणना करने योग्य कार्डिनिटी और ऑर्डर को मूल संग्रह को प्रभावित नहीं किया जाएगा। – KeithS
मैं एक iterator में एक IEnumerable लपेटकर अंतर्निहित कनेक्शन के साथ monkeying से प्राप्तकर्ताओं को रोकने के लिए सुझाव है कि नहीं होगा में ढाला नहीं जा सकता है।
public struct WrappedEnumerable<T> : IEnumerable<T>
{
IEnumerable<T> _dataSource;
public WrappedEnumerable(IEnumerable<T> dataSource)
{
_dataSource = dataSource;
}
public IEnumerator<T> GetEnumerator()
{
return _dataSource.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return ((System.Collections.IEnumerable)_dataSource).GetEnumerator();
}
}
संपत्तियों की वापसी प्रकार IEnumerable<T>
, WrappedEnumerable<T>
IEnumerable<T>
करने से प्रकार बलात्कार संरचना बॉक्स और व्यवहार और प्रदर्शन मैच होगा एक वर्ग के उन लोगों के है: मेरा झुकाव की तरह एक आवरण कुछ का उपयोग किया जाएगा । यदि, हालांकि, गुणों को लौटने वाले प्रकार WrappedEnumerable<T>
के रूप में परिभाषित किया गया था, तो उन मामलों में एक मुक्केबाजी चरण को सहेजना संभव होगा जहां कॉलिंग कोड या तो WrappedEnumerable<T>
की संपत्ति पर लौटाएगा (संभवतः var myKeys = myCollection.Keys;
जैसे कुछ के परिणामस्वरूप) या बस "foreach" लूप में सीधे संपत्ति का उपयोग करता है। ध्यान दें कि GetEnumerator()
द्वारा लौटाए गए गणक एक संरचना होगी, जिसे अभी भी किसी भी मामले में बॉक्स किया जाना होगा।
कक्षा के बजाय संरचना का उपयोग करने का प्रदर्शन लाभ आम तौर पर काफी मामूली होगा; अवधारणात्मक रूप से, हालांकि, एक संरचना का उपयोग सामान्य सिफारिश के साथ फिट होगा कि गुण नए ढेर ऑब्जेक्ट उदाहरण नहीं बनाते हैं। एक नया संरचना उदाहरण तैयार करना जिसमें मौजूदा ढेर ऑब्जेक्ट का संदर्भ कुछ भी नहीं है, वह बहुत सस्ता है।यहां परिभाषित एक संरचना का उपयोग करने का सबसे बड़ा नुकसान यह होगा कि यह कॉलिंग कोड पर लौटाई गई चीज़ के व्यवहार में बंद हो जाएगा, जबकि IEnumerable<T>
लौटने पर अन्य दृष्टिकोणों की अनुमति होगी।
भी ध्यान दें कि यह कुछ मामलों में किसी भी मुक्केबाजी के लिए आवश्यकता को खत्म करने और सी # और vb.net foreach
पाश में बतख टाइपिंग अनुकूलन शोषण करता है, तो एक एक प्रकार की तरह इस्तेमाल किया संभव हो सकता है:
public struct FancyWrappedEnumerable<TItems,TEnumerator,TDataSource> : IEnumerable<TItems> where TEnumerator : IEnumerator<TItems>
{
TDataSource _dataSource;
Func<TDataSource,TEnumerator> _convertor;
public FancyWrappedEnumerable(TDataSource dataSource, Func<TDataSource, TEnumerator> convertor)
{
_dataSource = dataSource;
_convertor = convertor;
}
public TEnumerator GetEnumerator()
{
return _convertor(_dataSource);
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return _convertor(_dataSource);
}
}
convertor
प्रतिनिधि एक स्थिर प्रतिनिधि हो सकता है, और इस प्रकार रन-टाइम (कक्षा प्रारंभिकरण के बाहर) पर किसी भी ढेर-वस्तु निर्माण की आवश्यकता नहीं होती है। इस दृष्टिकोण का उपयोग करते हुए, यदि कोई List<int>
से एक गणक वापस करना चाहता था, तो संपत्ति वापसी प्रकार FancyWrappedEnumerable<int, List<int>.Enumerator, List>
होगा। शायद उचित अगर कॉलर ने सीधे foreach
लूप में या var
घोषणा में सीधे संपत्ति का उपयोग किया, लेकिन बदले में अगर कॉलर इस प्रकार के भंडारण स्थान को ऐसे तरीके से घोषित करना चाहता था जो var
का उपयोग नहीं कर सके।
- 1. एक आईनेमरेबल विधि को डिबग करना
- 2. क्या यूआरएल में डीबी आंतरिक आईडी का पर्दाफाश करना एक बुरा अभ्यास है?
- 3. क्या windows.screen का उपयोग करना सुरक्षित है?
- 4. मुझे एक आईनेमरेबल या IList का उपयोग करना चाहिए?
- 5. एक विश्वसनीय API का उपयोग करना - क्या यह सुरक्षित है?
- 6. जब मैं एक आईनेमरेबल
- 7. क्या कोड में डीबीएल_एमएक्स का उपयोग करना सुरक्षित है?
- 8. एक प्लगइन बनाएं, घटनाओं का पर्दाफाश करें
- 9. खराब अभ्यास: एक इंटरफेस में एक घटना का पर्दाफाश?
- 10. EJBContext getContextData का उपयोग करना - क्या यह सुरक्षित है?
- 11. क्या std :: stack iterators का पर्दाफाश करता है?
- 12. रूबी प्रतीकों का पर्दाफाश क्यों करता है?
- 13. आईनेमरेबल <T> का रूपांतरण IList
- 14. एक BOOL संपत्ति का उपयोग करना
- 15. एक आईनेमरेबल <string>
- 16. क्या कुकीज़ सुरक्षित करना संभव है?
- 17. क्या अभी भी ASIHTTPRequest का उपयोग करना सुरक्षित है?
- 18. सी # आईनेमेरेबल रहस्य का संशोधन, मेरे आईनेमरेबल को संशोधित करना क्या है?
- 19. क्या javax.xml.ws.Service वस्तुओं का पुन: उपयोग करना सुरक्षित है?
- 20. एक आईनेमरेबल संग्रह में एकल तत्व जोड़ने का सबसे अच्छा तरीका क्या है?
- 21. क्या यह एक ही यूआरएल पर रीडायरेक्ट करना सुरक्षित है?
- 22. ईएफ 4 + एमवीवीएम - व्यूमोडेल में इकाइयों का पर्दाफाश करें?
- 23. क्या एक पासवर्ड फ़ील्ड के रूप में एक संपत्ति ग्रिड में दिखाए गए एक संपत्ति को चिह्नित करना संभव है
- 24. क्या यह एक एसएलएल कंटेनर असाइन करना सुरक्षित है?
- 25. वैश्विक नामस्थान में आवश्यकता जेएस मॉड्यूल का पर्दाफाश करने का सही तरीका क्या है?
- 26. एक वेब सेवा सुरक्षित करना
- 27. क्या NSLocalizedString() में "असली" कुंजी का उपयोग करना सुरक्षित है? क्या गारंटीकृत फ़ॉलबैक भाषा है?
- 28. क्या एक कार्यकर्ता धागे में SHFileOperation का उपयोग करना सुरक्षित है?
- 29. $ .support.cors = true का उपयोग करना सुरक्षित है; jQuery में?
- 30. क्या जावास्क्रिप्ट स्विच स्टेटमेंट में सख्त तुलना करना सुरक्षित है?
कुछ चेतावनियां जबकि संपत्ति के रूप में संग्रह का उपयोग कर रहे हैं, MSDN https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/guidelines-for-collections से इस डिजाइन दिशानिर्देश लिंक की जाँच करें –