क्या इंटरफेस के लिए इंटरफेस को लागू करना सुरक्षित है?


92

मुझे सीएलआर के माध्यम से सीएलआर में इंटरफेस को लागू करने के लिए संरचनाओं के लिए कैसे बुरा है, इसके बारे में कुछ पढ़ना याद है, लेकिन मुझे इसके बारे में कुछ भी पता नहीं लग सकता है। क्या यह खराब है? क्या ऐसा करने के अनपेक्षित परिणाम हैं?

public interface Foo { Bar GetBar(); }
public struct Fubar : Foo { public Bar GetBar() { return new Bar(); } }

जवाबों:


45

इस सवाल पर कई बातें चल रही हैं ...

एक इंटरफ़ेस को लागू करने के लिए एक संरचना के लिए संभव है, लेकिन ऐसी चिंताएं हैं जो कास्टिंग, परिवर्तनशीलता और प्रदर्शन के बारे में आती हैं। अधिक जानकारी के लिए इस पोस्ट को देखें: https://docs.microsoft.com/en-us/archive/blogs/abhinaba/c-structs-and-interface

सामान्य तौर पर, उन वस्तुओं के लिए संरचनाओं का उपयोग किया जाना चाहिए जिनमें मूल्य-प्रकार के शब्दार्थ हैं। एक संरचना पर एक इंटरफ़ेस को लागू करने से आप बॉक्सिंग चिंताओं में भाग सकते हैं क्योंकि संरचना और इंटरफ़ेस के बीच संरचना आगे और पीछे डाली जाती है। मुक्केबाजी के परिणामस्वरूप, संरचना की आंतरिक स्थिति को बदलने वाले संचालन ठीक से व्यवहार नहीं कर सकते हैं।


3
"मुक्केबाजी के परिणामस्वरूप, संरचना की आंतरिक स्थिति को बदलने वाले संचालन ठीक से व्यवहार नहीं कर सकते हैं।" एक उदाहरण दें और उत्तर प्राप्त करें।

2
@Will: यह निश्चित नहीं है कि आप अपनी टिप्पणी में क्या उल्लेख कर रहे हैं। मेरे द्वारा संदर्भित ब्लॉग पोस्ट में एक उदाहरण है जो दिखाता है कि संरचना पर इंटरफ़ेस विधि को कॉल करने से वास्तव में आंतरिक मूल्य नहीं बदलता है।
स्कॉट डोरमैन

12
@ScottDorman: कुछ मामलों में, संरचनाएं लागू करने से इंटरफेस बॉक्सिंग से बचने में मदद मिल सकती है । प्रमुख उदाहरण हैं IComparable<T>और IEquatable<T>Fooप्रकार के एक चर में एक संरचना को संग्रहीत करने के IComparable<Foo>लिए बॉक्सिंग की आवश्यकता होती है, लेकिन अगर एक सामान्य प्रकार Tको IComparable<T>किसी को विवश किया जाता है , तो इसकी तुलना दूसरे Tसे बॉक्स के बिना हो सकती है , और इसके Tअलावा अन्य के बारे में कुछ भी जानने के बिना यह बाधा को लागू करता है। इस तरह के लाभप्रद व्यवहार को केवल इंटरफ़ेस को लागू करने की क्षमता द्वारा संभव बनाया गया है। कहा गया है कि ...
सुपरकैट

3
... यह अच्छा रहा हो सकता है अगर यह घोषित करने के साधन थे कि एक विशेष इंटरफ़ेस को केवल अनबॉक्सेड संरचनाओं पर लागू किया जाना चाहिए, क्योंकि कुछ संदर्भ हैं जहां यह क्लास ऑब्जेक्ट या वांछित संरचना के लिए बॉक्सिंग संरचना के लिए संभव नहीं होगा। व्यवहार।
सुपरकैट

2
"संरचना का उपयोग उन वस्तुओं के लिए किया जाना चाहिए जिनमें मूल्य-प्रकार के शब्दार्थ हैं। ... ऐसे ऑपरेशन जो संरचना की आंतरिक स्थिति को बदलते हैं, वे ठीक से व्यवहार नहीं कर सकते हैं।" क्या वास्तविक समस्या यह नहीं है कि मूल्य-प्रकार के शब्दार्थ और परिवर्तनशीलता में अच्छी तरह से मिश्रण नहीं है?
jpmc26

183

चूंकि किसी और ने स्पष्ट रूप से यह उत्तर नहीं दिया है, इसलिए मैं निम्नलिखित जोड़ूंगा:

एक संरचना पर एक इंटरफ़ेस को लागू करने का कोई नकारात्मक परिणाम नहीं है।

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

  • लॉकिंग उद्देश्यों के लिए परिणामी वस्तु का उपयोग करना (किसी भी तरह से बहुत बुरा विचार)
  • संदर्भ समानता शब्दार्थ का उपयोग करना और एक ही संरचना से दो बॉक्सिंग मूल्यों के लिए काम करने की अपेक्षा करना।

इन दोनों की संभावना नहीं होगी, इसके बजाय आप निम्नलिखित में से एक होने की संभावना है:

जेनेरिक्स

शायद इंटरफेस को लागू करने के लिए कई उचित कारण हैं ताकि उन्हें बाधा के साथ एक सामान्य संदर्भ में इस्तेमाल किया जा सके । जब इस तरह से चर का उपयोग किया जाता है:

class Foo<T> : IEquatable<Foo<T>> where T : IEquatable<T>
{
    private readonly T a;

    public bool Equals(Foo<T> other)
    {
         return this.a.Equals(other.a);
    }
}
  1. एक प्रकार के पैरामीटर के रूप में संरचना का उपयोग सक्षम करें
    • इसलिए जब तक कोई अन्य बाधा new()या classउपयोग नहीं किया जाता है।
  2. इस तरह से उपयोग की जाने वाली संरचनाओं पर मुक्केबाजी से बचने की अनुमति दें।

तब यह एक इंटरफ़ेस संदर्भ नहीं है, इस प्रकार इसमें जो कुछ भी रखा जाता है उसका एक बॉक्स नहीं होता है। इसके अलावा जब c # कंपाइलर जेनेरिक कक्षाओं को संकलित करता है और टाइप पैरामीटर T के इंस्टेंस पर परिभाषित आवृत्ति विधियों के इनवोकेशन सम्मिलित करने की आवश्यकता होती है, तो यह विवश ऑपकोड का उपयोग कर सकता है :

यदि यह टाइप वैल्यू टाइप है और यह टाइप एप्लाइंसेज विधि है, तो ptr को इस टाइप द्वारा मेथड के कार्यान्वयन के लिए कॉल विधि इंस्ट्रक्शन के 'इस' पॉइंटर के रूप में अनमॉडिफाइड किया जाता है।

यह बॉक्सिंग से बचा जाता है और चूंकि मूल्य प्रकार इंटरफ़ेस को लागू कर रहा है इसलिए इसे विधि को लागू करना चाहिए , इस प्रकार कोई बॉक्सिंग नहीं होगी। ऊपर के उदाहरण में Equals()मंगलाचरण this.a पर कोई बॉक्स के साथ किया जाता है 1

कम घर्षण एपीआई

अधिकांश संरचनाओं में आदिम-जैसे शब्दार्थ होने चाहिए जहां बिटवाइज़ समान मानों को समान 2 माना जाता है । रनटाइम निहितार्थ में इस तरह के व्यवहार की आपूर्ति करेगा Equals()लेकिन यह धीमा हो सकता है। इसके अलावा, इस निहित समानता को लागू करने के रूप में उजागर नहीं किया जाता है IEquatable<T>और इस तरह से शब्दकोशों के लिए कुंजी के रूप में आसानी से उपयोग की जा रही संरचना को रोकता है जब तक कि वे स्पष्ट रूप से खुद को लागू नहीं करते हैं। इसलिए कई सार्वजनिक संरचना प्रकारों के लिए यह घोषित करना आम है कि वे लागू करें IEquatable<T>(जहांT सीएलआर बीसीएल के भीतर कई मौजूदा मूल्य प्रकारों के व्यवहार के अनुरूप इस आसान और बेहतर प्रदर्शन को स्वयं हैं) ।

BCL में सभी प्राइमिटिव न्यूनतम पर लागू होते हैं:

  • IComparable
  • IConvertible
  • IComparable<T>
  • IEquatable<T>(और IEquatable)

कई भी लागू करते हैं IFormattable , आगे सिस्टम परिभाषित मूल्य प्रकार जैसे डेटटाइम, टाइमस्पैन और गाइड इन में से कई या सभी को लागू करते हैं। यदि आप एक जटिल संख्या संरचना या कुछ निश्चित चौड़ाई के पाठ मानों की तरह समान रूप से 'व्यापक रूप से उपयोगी' को लागू कर रहे हैं तो इनमें से कई सामान्य इंटरफेस (सही ढंग से) को लागू करने से आपकी संरचना अधिक उपयोगी और उपयोगी हो जाएगी।

बहिष्करण

जाहिर है अगर इंटरफ़ेस दृढ़ता से उत्परिवर्तन (जैसे ICollection) का अर्थ है तो इसे लागू करना एक बुरा विचार है क्योंकि इसका मतलब यह होगा कि आपने या तो संरचनात्मक परिवर्तनशील बना दिया था (पहले से वर्णित त्रुटियों के कारण जहां मूल के बजाय बॉक्सिंग मूल्य पर संशोधन होते हैं ) या आप Add()अपवादों की तरह या फेंकने के तरीकों के निहितार्थों को अनदेखा करके उपयोगकर्ताओं को भ्रमित करते हैं।

कई इंटरफेस एकरूपता (जैसे IFormattable) का मतलब नहीं है और एक निरंतर फैशन में कुछ कार्यक्षमता को उजागर करने के लिए मुहावरेदार तरीके के रूप में काम करते हैं। अक्सर संरचना का उपयोगकर्ता इस तरह के व्यवहार के लिए किसी भी बॉक्सिंग ओवरहेड की परवाह नहीं करेगा।

सारांश

जब समझदारी से किया जाता है, तो अपरिवर्तनीय मूल्य प्रकारों पर, उपयोगी इंटरफेस का कार्यान्वयन एक अच्छा विचार है


टिप्पणियाँ:

1: ध्यान दें कि कंपाइलर इसका उपयोग तब कर सकते हैं जब चर पर आभासी तरीकों का प्रयोग किया जाता है जो एक विशिष्ट संरचना प्रकार के लिए जाने जाते हैं लेकिन जिसमें वर्चुअल विधि को लागू करना आवश्यक होता है। उदाहरण के लिए:

List<int> l = new List<int>();
foreach(var x in l)
    ;//no-op

सूची द्वारा लौटाए गए एन्यूमरेटर एक संरचना है, सूची की गणना करते समय आवंटन से बचने के लिए एक अनुकूलन (कुछ दिलचस्प परिणामों के साथ )। हालाँकि, फॉर्च्यून के शब्दार्थ यह निर्दिष्ट करते हैं कि यदि एन्यूमरेटर लागू हो जाता है, तो पुनरावृत्ति पूरा होने के IDisposableबाद Dispose()उसे कॉल किया जाएगा। जाहिर है कि बॉक्सिंग कॉल के माध्यम से ऐसा होने से एन्यूमरेटर की संरचना (वास्तव में यह बदतर होगी) का कोई लाभ समाप्त हो जाएगा। इससे भी बदतर बात यह है कि अगर डिस्पोजल कॉल किसी तरह से एन्यूमरेटर की स्थिति को संशोधित करता है तो यह बॉक्सिंग उदाहरण पर होगा और जटिल मामलों में कई सूक्ष्म कीड़े पेश किए जा सकते हैं। इसलिए इस प्रकार की स्थिति में उत्सर्जित IL है:

IL_0001: newobj System.Collections.Generic.List..ctor
IL_0006: stloc.0     
IL_0007: एनओपी         
IL_0008: ldloc.0     
IL_0009: callvirt System.Collections.Generic.List.GetEnumerator
IL_000E: stloc.2     
IL_000F: br.s IL_0019
IL_0011: ldloca.s 02 
IL_0013: Call System.Collections.Generic.List.get_Current
IL_0018: stloc.1     
IL_0019: ldloca.s 02 
IL_001B: Call System.Collections.Generic.List.MoveNext
IL_0020: stloc.3     
IL_0021: ldloc.3     
IL_0022: brtrue.s IL_0011
IL_0024: छोड़ दें। IL_0035
IL_0026: ldloca.s 02 
IL_0028: विवश। System.Collections.Generic.List.Enumerator
IL_002E: callvirt System.IDisposable.Dispose
IL_0033: एनओपी         
IL_0034: अंतिम रूप से  

इस प्रकार आईडीसोपायरी के क्रियान्वयन से कोई प्रदर्शन समस्याएँ उत्पन्न नहीं होती हैं और एन्युमरेटर का (पछतावा) उत्परिवर्तित पहलू संरक्षित होता है, डिस्पोज़ विधि वास्तव में कुछ भी करना चाहिए!

2: डबल और फ्लोट इस नियम के अपवाद हैं जहां NaN मूल्यों को समान नहीं माना जाता है।


1
साइट egheadcafe.com चली गई है, लेकिन अपनी सामग्री को बनाए रखने के साथ एक अच्छा काम नहीं किया है। मैंने कोशिश की, लेकिन ओपी के ज्ञान की कमी के लिए, उदाहरण के लिए , उदाहरण के लिए eggheadcafe.com/software/aspnet/31702392/… प्राप्त नहीं कर सका । (एक उत्कृष्ट सारांश के लिए पीएस +1)।
हाबिल

2
यह एक महान उत्तर है, लेकिन मुझे लगता है कि आप "सारांश" को "टीएल; डीआर" के रूप में शीर्ष पर ले जाकर इसे सुधार सकते हैं। निष्कर्ष प्रदान करने से पहले पाठक को पता चलता है कि आप चीजों के साथ कहां जा रहे हैं।
हंस

एक structको कास्टिंग करते समय संकलक चेतावनी होनी चाहिए interface
जलाल

8

कुछ मामलों में यह एक इंटरफ़ेस को लागू करने के लिए एक संरचना के लिए अच्छा हो सकता है (यदि यह कभी भी उपयोगी नहीं था, तो यह संदिग्ध है कि .net के निर्माता इसके लिए प्रदान करेंगे)। यदि कोई संरचना केवल पढ़ने के लिए इंटरफेस को लागू करती है IEquatable<T>, जैसे कि स्टोरेज लोकेशन में स्ट्रक्चर को स्टोर करना (वेरिएबल, पैरामीटर, एरे एलीमेंट, इत्यादि) टाइप करने के लिए IEquatable<T>यह आवश्यक होगा कि इसे बॉक्स किया जाए (प्रत्येक स्ट्रक्चर टाइप वास्तव में दो प्रकार की चीजों को परिभाषित करता है: एक स्टोरेज स्थान प्रकार जो एक मान प्रकार के रूप में व्यवहार करता है और एक ढेर-प्रकार का प्रकार जो एक वर्ग प्रकार के रूप में व्यवहार करता है, पहला स्पष्ट रूप से दूसरे के लिए परिवर्तनीय है - "मुक्केबाजी" - और दूसरा स्पष्ट कलाकारों के माध्यम से पहले में परिवर्तित किया जा सकता है - "बॉक्स से निकालना")। बॉक्सिंग के बिना एक इंटरफ़ेस की संरचना के कार्यान्वयन का शोषण करना संभव है, हालांकि, उपयोग को विवश कहा जाता है।

उदाहरण के लिए, यदि किसी के पास एक विधि थी CompareTwoThings<T>(T thing1, T thing2) where T:IComparable<T> , तो ऐसी विधि thing1.Compare(thing2)बॉक्स thing1या बिना बुलाए हो सकती है thing2। यदि thing1ऐसा होता है, जैसे, ए, Int32रन-टाइम को पता चल जाएगा कि यह कब के लिए कोड बनाता है CompareTwoThings<Int32>(Int32 thing1, Int32 thing2)। चूंकि यह विधि को होस्ट करने वाली चीज़ के सटीक प्रकार और पैरामीटर के रूप में पारित होने वाली चीज़ को जान लेगा, इसलिए इसे दोनों में से किसी एक को बॉक्स नहीं करना होगा।

इंटरफेस को लागू करने वाली संरचनाओं के साथ सबसे बड़ी समस्या यह है कि एक संरचना जो इंटरफ़ेस प्रकार के स्थान में संग्रहीत होती है Object, या ValueType(अपने प्रकार के स्थान के विपरीत) एक वर्ग वस्तु के रूप में व्यवहार करेगी। केवल-पढ़ने के लिए इंटरफेस के लिए यह आम तौर पर एक समस्या नहीं है, लेकिन एक म्यूटिंग इंटरफ़ेस के लिए IEnumerator<T>यह कुछ अजीब शब्दार्थों का उत्पादन कर सकता है।

उदाहरण के लिए, निम्नलिखित कोड पर विचार करें:

List<String> myList = [list containing a bunch of strings]
var enumerator1 = myList.GetEnumerator();  // Struct of type List<String>.IEnumerator
enumerator1.MoveNext(); // 1
var enumerator2 = enumerator1;
enumerator2.MoveNext(); // 2
IEnumerator<string> enumerator3 = enumerator2;
enumerator3.MoveNext(); // 3
IEnumerator<string> enumerator4 = enumerator3;
enumerator4.MoveNext(); // 4

enumerator1पहले तत्व को पढ़ने के लिए चिह्नित किया गया कथन # 1 प्रमुख होगा । उस प्रगणक की स्थिति की प्रतिलिपि बनाई जाएगी enumerator2। चिह्नित कथन # 2 दूसरे तत्व को पढ़ने के लिए उस कॉपी को आगे बढ़ाएगा, लेकिन प्रभावित नहीं करेगा enumerator1। उस दूसरे एन्यूमरेटर की स्थिति को फिर कॉपी enumerator3किया जाएगा, जो कि चिह्नित स्टेटमेंट # 3 से उन्नत होगा। फिर, क्योंकि enumerator3और enumerator4दोनों संदर्भ प्रकार के होते हैं, एक संदर्भ के लिए enumerator3तो में कॉपी किया जायेगाenumerator4 , इसलिए चिह्नित बयान को प्रभावी ढंग से आगे बढ़ाएंगे दोनों enumerator3 और enumerator4

कुछ लोग यह दिखावा करने की कोशिश करते हैं कि मूल्य प्रकार और संदर्भ प्रकार दोनों प्रकार के हैं Object, लेकिन यह वास्तव में सच नहीं है। वास्तविक मूल्य प्रकार परिवर्तनीय हैं Object, लेकिन इसके उदाहरण नहीं हैं। इसका एक उदाहरण List<String>.Enumeratorउस प्रकार के स्थान में संग्रहीत किया जाता है जो एक मूल्य-प्रकार है और एक मूल्य प्रकार के रूप में व्यवहार करता है; इसे किसी प्रकार के स्थान पर कॉपी करना इसे IEnumerator<String>संदर्भ प्रकार में बदल देगा, और यह एक संदर्भ प्रकार के रूप में व्यवहार करेगा । उत्तरार्द्ध एक तरह का है Object, लेकिन पूर्व नहीं है।

BTW, एक जोड़े को अधिक नोट्स: (1) सामान्य तौर पर, उत्परिवर्तनीय वर्ग प्रकारों में उनके Equalsतरीकों का संदर्भ संदर्भ समानता होनी चाहिए , लेकिन ऐसा करने के लिए एक बॉक्सेड संरचना के लिए कोई सभ्य तरीका नहीं है; (2) अपने नाम के बावजूद, ValueTypeएक वर्ग प्रकार है, एक मूल्य प्रकार नहीं है; सभी प्रकार से प्राप्त System.Enumमूल्य प्रकार के होते हैं, के रूप में सभी प्रकार के जो से निकाले जाते हैं कर रहे हैं ValueTypeके अपवाद के साथ System.Enum, लेकिन दोनों ValueTypeऔर System.Enumवर्ग प्रकार हैं।


3

संरचना को मूल्य प्रकार के रूप में लागू किया जाता है और कक्षाएं संदर्भ प्रकार होती हैं। यदि आपके पास फू प्रकार का एक चर है, और आप इसमें फ़ुबर का एक उदाहरण संग्रहीत करते हैं, तो यह एक संदर्भ प्रकार में "बॉक्स" करेगा, इस प्रकार पहली जगह में एक संरचना का उपयोग करने के लाभ को हराया।

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


क्या यह ऐसे प्राइमेटर्स के लिए काम करता है जो इंटरफेस को लागू करते हैं, भी?
एओटाल्क्स

3

(अच्छी तरह से जोड़ने के लिए कुछ भी प्रमुख नहीं मिला है, लेकिन यहाँ अभी तक संपादन संपादन नहीं है ..)
बिल्कुल सुरक्षित। संरचनाओं पर इंटरफेस लागू करने के साथ कुछ भी अवैध नहीं है। हालाँकि आपको सवाल करना चाहिए कि आप ऐसा क्यों करना चाहते हैं।

हालांकि एक संरचना के लिए एक इंटरफ़ेस संदर्भ प्राप्त करना BOX होगा यह होगा। तो प्रदर्शन दंड और इतने पर।

एकमात्र मान्य परिदृश्य जिसके बारे में मैं अभी सोच सकता हूं, उसका वर्णन यहां मेरी पोस्ट में किया गया है । जब आप किसी संग्रह में संग्रहीत एक संरचना की स्थिति को संशोधित करना चाहते हैं, तो आपको इसे संरचना पर उजागर एक अतिरिक्त इंटरफ़ेस के माध्यम से करना होगा।


यदि कोई Int32ऐसी विधि से गुजरता है जो एक सामान्य प्रकार को स्वीकार करता है T:IComparable<Int32>(जो या तो विधि का सामान्य प्रकार का पैरामीटर हो सकता है, या विधि का वर्ग), तो वह विधि Compareबॉक्स के बिना पास की गई वस्तु पर विधि का उपयोग करने में सक्षम होगी ।
सुपरकैट

1

मुझे लगता है कि समस्या यह है कि यह मुक्केबाजी का कारण बनता है क्योंकि संरचना मूल्य प्रकार हैं इसलिए थोड़ा सा प्रदर्शन जुर्माना है।

यह लिंक बताता है कि इसके साथ अन्य मुद्दे हो सकते हैं ...

http://blogs.msdn.com/abhinaba/archive/2005/10/05/477238.aspx


0

एक इंटरफ़ेस को लागू करने वाली संरचना के लिए कोई परिणाम नहीं हैं। उदाहरण के लिए अंतर्निहित सिस्टम संरचना जैसे इंटरफेस को लागू करती है IComparableऔर IFormattable


0

एक इंटरफ़ेस को लागू करने के लिए एक मूल्य प्रकार के लिए बहुत कम कारण है। चूंकि आप एक मूल्य प्रकार को उप-वर्ग नहीं कर सकते हैं, आप हमेशा इसे अपने ठोस प्रकार के रूप में संदर्भित कर सकते हैं।

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

बेशक, एक इंटरफ़ेस लागू करके, आप संरचना को बॉक्सिंग कर रहे हैं, इसलिए यह अब ढेर पर बैठता है, और आप इसे अब और मूल्य से पारित नहीं कर पाएंगे ... यह वास्तव में मेरी राय को पुष्ट करता है कि आपको बस एक वर्ग का उपयोग करना चाहिए इस दशा में।


कंक्रीट कार्यान्वयन के बजाय आप कितनी बार IComparable पास करते हैं?
फ्लाईसवाट

आपको IComparableमान को बॉक्स करने के लिए पास होने की आवश्यकता नहीं है । केवल एक विधि को कॉल करके जो IComparableएक मूल्य प्रकार के साथ अपेक्षा करता है जो इसे लागू करता है आप मूल्य प्रकार को बॉक्स करेंगे।
एंड्रयू हरे

1
@AndrewHare: संकुचित जेनरिक बॉक्सिंग के बिना IComparable<T>प्रकार की संरचनाओं पर लागू होने के तरीकों की अनुमति देते हैं T
सुपरकैट

-10

संरचनाएं उन वर्गों की तरह हैं जो स्टैक में रहते हैं। मुझे कोई कारण नहीं दिखता कि उन्हें "असुरक्षित" क्यों होना चाहिए।


सिवाय उनमें विरासत की कमी है।
फ्लाईसवाट

7
मुझे इस उत्तर के हर हिस्से से असहमत होना होगा; वे जरूरी स्टैक पर नहीं रहते हैं, और कॉपी-शब्दार्थ कक्षाओं के लिए बहुत अलग हैं।
मार्क Gravell

1
वे अपरिवर्तनीय हैं, संरचना के अत्यधिक उपयोग से आपकी याददाश्त उदास हो जाएगी :(
टेमन शिपही

1
@Teomanshipahi वर्ग उदाहरणों का अत्यधिक उपयोग आपके कचरा संग्रहकर्ता को पागल बना देगा।
IllidanS4

4
20k + प्रतिनिधि वाले किसी व्यक्ति के लिए, यह उत्तर अस्वीकार्य है।
क्रीथिक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.