2010-09-04 12 views
5

विवरण के वैसे, सी # में यह मान प्रकार ले:क्या केवल मूल्य-प्रकार का उपयोग करके संदर्भ-चक्र बनाना संभव है?

struct ObjRef 
{ 
    public object Value; 
    public ObjRef(object value) { Value = value; } 
} 

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

मेरा सवाल यह है कि .NET में ऐसा ऑब्जेक्ट ग्राफ़ कभी भी बनाया जा सकता है या नहीं। वैचारिक रूप से, निर्माण, यदि वह मौजूद है, इस तरह जाना होगा:

object left = new ObjRef(); 
object right = new ObjRef(left); 
left.Value = right; 

लेकिन स्पष्ट रूप से, अंतिम पंक्ति वहाँ नहीं है मान्य सी #।

((ObjRef)left).Value = right; 

के रूप में कास्ट left unboxes और आप एक प्रति परिवर्तनशील अंत परिणाम प्राप्त नहीं करता है: अंतिम पंक्ति बनाना। तो कम से कम सीधे सी # में, ऐसा लगता है कि निर्माण संभव नहीं है।

क्या किसी को पता है कि निर्माण प्रतिबिंब, असुरक्षित कोड, dynamic, आईएल कोड, या किसी अन्य तरीके से उपयोग किया जा सकता है? या, क्या कोई दिखा सकता है कि सीएलआर प्रभावी रूप से ऐसे संदर्भ-चक्र को रोकता है?

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


संपादित

रूप Brian का सुझाव दिया, यह वास्तव में संभव हो, यह unboxing बिना बॉक्स्ड मूल्य को संशोधित करने के लिए एक इंटरफेस प्रकार के बजाय मान प्रकार के लिए यह कास्टिंग द्वारा है।

interface IObjRef 
{ 
    IObjRef Value { get; set; } 
} 

struct ObjRef : IObjRef 
{ 
    IObjRef value; 
    public IObjRef Value { get { return value; } set { this.value = value; } } 
    public ObjRef(IObjRef value) { this.value = value; } 
} 

तो संदर्भ चक्र मैं का वर्णन इस तरह का निर्माण किया जा सकता है::

IObjRef left = new ObjRef(); 
IObjRef right = new ObjRef(left); 
left.Value = right; 

कौन सा मूल रूप से कारण # 72 के साथ हमें छोड़ देता है क्यों परिवर्तनशील मूल्य-प्रकार के बुरे होते हैं तो यह कोड दिया।

उत्तर

2

यह एक इंटरफेस का उपयोग करके और मूल्य प्रकार इंटरफेस को लागू करने और एक-दूसरे को संदर्भित करने के लिए संभव है। यह उन्हें बॉक्स किए गए मानों के माध्यम से एक चक्र बनाने की अनुमति देता है क्योंकि इंटरफेस संदर्भ के साथ उपयोग की जाने वाली संरचना को बॉक्स किया जाएगा।

त्वरित नमूना

interface ICycle 
{ 
    void SetOther(ICycle other); 
} 

struct Cycle : ICycle 
{ 
    ICycle value; 
    public void SetOther(ICycle other) 
    { 
     value = other; 
    } 
} 

class Example 
{ 
    static void CreateCycle() 
    { 
     ICycle left = new Cycle(); // Left is now boxed 
     ICycle right = new Cycle(); // Right is now boxed 
     left.SetOther(right); 
     right.SetOther(left); // Cycle 
    } 
} 

मैं हालांकि सोच क्या लाभ यह आप दे देंगे के बारे में ब्रायन के सवाल को साझा करें।

+0

यह कोई फायदा नहीं देता है; जैसा कि मैंने सवाल में कहा है, मैं इस चक्र को नहीं बनाना चाहता हूं। इसके अलावा, मैं कभी भी एक परिवर्तनीय मूल्य-प्रकार नहीं लिखूंगा। हालांकि, मनमानी ऑब्जेक्ट ग्राफ़ पर काम कर रहे एक क्रमबद्ध फॉर्मेटर को संभावना के बारे में पता होना चाहिए, और यह मानकर एक अनंत लूप दर्ज नहीं करना चाहिए कि संदर्भ प्रकार हमेशा पेड़ बनाते हैं और चक्र नहीं। यह उस क्रम को भी प्रभावित कर सकता है जिसमें वस्तुओं को deserialized किया जाना है। –

+0

संयोग से, बॉक्स किए गए मान प्रकार वास्तव में मूल्य प्रकार नहीं हैं। सीएलआर के भीतर, उन्हें कक्षाओं के रूप में संभाला जाता है, और वे कक्षाओं की तरह व्यवहार करते हैं। एकमात्र चीज जो उन्हें विशेष बनाती है वह यह है कि * भंडारण स्थान * जिसका घोषित प्रकार मूल्य प्रकार से प्राप्त होता है, वस्तु के संदर्भ के बजाय किसी आइटम के लिए डेटा रखेगा। – supercat

1

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

मुझे अस्पष्टता महसूस हो रही है कि यह संभव है, हालांकि मुझे यकीन है कि मुझे ऐसा क्यों लगता है। सहायक, हुह?

0

मुझे नहीं पता था कि संरचनाएं इंटरफेस को कार्यान्वित कर सकती हैं। यह वास्तव में विचित्र लगता है; इसके लिए क्या अच्छा है? सामान्य रूप से संरचनाओं के लिए नापसंद है, या गुणों और विधियों के साथ संरचनाओं के लिए जो उन पर कार्य करते हैं? यह बहुत बुरा है। नेट किसी को कुछ संरचना गुणों और विधियों को म्यूटेटर के रूप में घोषित करने की अनुमति नहीं देता है, जिसका उपयोग "केवल पढ़ने" संरचनाओं पर किया जाएगा।

+1

पुन: इंटरफेस और संरचनाएं: यह वही कारण है कि इंटरफेस संदर्भ प्रकारों पर उपयोगी हैं - आपको प्रोग्रामिंग इंटरफ़ेस निर्दिष्ट करने की अनुमति देने के लिए जो अंतर्निहित प्रकार की परवाह नहीं करता है। एक मूल्य प्रकार आईसीओपरपेबल और आईक्वाटेबल को काफी हद तक लागू कर सकता है और संग्रह कक्षाओं को उस प्रकार के बारे में धारणाएं करने की इजाजत देता है जो वे अन्यथा करने में सक्षम नहीं होंगे। – siride

+0

मैं iComparable और iEquatable के बारे में आपका बिंदु देखता हूं। मुझे लगता है कि समस्या यह है कि उन तरीकों से फ़्लैग करने का कोई तरीका नहीं है जो किसी ऑब्जेक्ट को उन लोगों से बदलते हैं जो नहीं करते हैं। ऐसा नहीं है कि इससे लोगों को "धोखा" देने की अनुमति नहीं मिलेगी, लेकिन यह सबसे आकस्मिक 'गेटचास' से बच जाएगी। – supercat

संबंधित मुद्दे

 संबंधित मुद्दे