2010-04-27 18 views
7

मुझे ऐसी स्थिति का सामना करना पड़ रहा है जहां मेरे पास निर्भर वस्तुएं हैं और मैं किसी ऑब्जेक्ट को हटाने और इसके सभी संदर्भों को हटाने में सक्षम होना चाहता हूं।सूचियों से वस्तुओं को हटाने और उनके लिए सभी संदर्भ

कहें कि मेरे पास नीचे दिए गए कोड की तरह एक ऑब्जेक्ट संरचना है, जिसमें शाखा प्रकार है जो दो नोड्स का संदर्भ देता है।

public class Node 
{ 
    // Has Some Data! 
} 

public class Branch 
{ 
    // Contains references to Nodes 
    public Node NodeA 
    public Node NodeB 
} 

public class Graph 
{ 
    public List<Node> Nodes; 
    public List<Branch> Branches; 
} 

अगर मैं ग्राफ़ कक्षा में नोड्स सूची में से एक नोड को हटाने, यह अभी भी संभव है कि एक या अधिक शाखा वस्तुओं अभी भी हटा दिया नोड का संदर्भ होता है इस प्रकार स्मृति में बनाए रखना है, जबकि वास्तव में मैं क्या काफी हद तक हटाए गए नोड को किसी भी संदर्भ में सेट करना होगा और कचरा संग्रह को किक करने दें।

प्रत्येक शाखा के माध्यम से गणना करने और अनुक्रमिक रूप से प्रत्येक नोड संदर्भ की जांच करने के अलावा, क्या कोई संदर्भ है कि मैं संदर्भ कैसे हटाता हूं प्रत्येक शाखा के उदाहरण में नोड में और वास्तव में किसी अन्य वर्ग जो हटाए गए नोड का संदर्भ देता है?

+1

क्या आप वास्तव में शाखा पर कोई डेटा संग्रहीत कर रहे हैं? यदि नहीं, तो आप पूरी तरह से उस वर्ग से छुटकारा पा सकते हैं और नोड कक्षा पर संबंधित नोड्स स्टोर कर सकते हैं। –

+0

हाय, हां, मैं कुछ अन्य डेटा संग्रहीत कर रहा हूं, उपरोक्त डेटा संरचना यह दिखाने के लिए एक साधारण उदाहरण था कि मेरे वास्तविक मॉडल के संदर्भ कहां हैं। – LiamV

उत्तर

1

शाखाओं उस पर है की एक सूची में शामिल करने के लिए अपने नोड बदलें। जब आप नोड को हटाते हैं तो आप इसे बंद कर देते हैं। स्पष्ट रूप से आप नोड्स और शाखाओं को जोड़ने और निकालने के लिए सभी विधियों को समाहित करते हैं ताकि बाहरी कोड संरचना को तोड़ न सके।

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

+0

आप सही हैं कि मुझे दी गई जानकारी के आधार पर नोड्स या शाखाओं की सूची की आवश्यकता नहीं है, लेकिन वहां ऐसे अन्य कारक हैं जिन्हें आप शायद विचार नहीं करेंगे। उदाहरण के लिए, यह डेटा वास्तव में डेटाबेस के भीतर संग्रहीत किया जाएगा, इसलिए प्रत्येक प्रकार की सूचियों के लिए यह उचित है, जो डेटाबेस तालिका में मानचित्र है। – LiamV

+0

यह संरचना * आसानी से * डेटाबेस में मानचित्र कर सकती है: नोड्स के लिए टेबल, किनारों के लिए तालिका, उनके बीच एफके संबंध। यह 100% एक रिलेशनल मॉडल है। ईएफ 4 किसी भी अतिरिक्त काम के बिना आलसी लोडिंग किनारों और नोड्स के आसपास सभी मुद्दों को संभाल सकता है। जब आप एक एंटिटी डेटा मॉडल में डेटाबेस आयात करते हैं, तो आप स्वचालित रूप से Node.Edges प्राप्त करते हैं। वास्तव में यह एक आसान को हटाने पर भी आसान हो जाएगा, जब आप इसे प्रत्येक नोड से स्वचालित रूप से हटा सकते हैं। –

0

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

+0

आपके सभी प्रतिक्रियाओं के लिए बहुत बहुत धन्यवाद, यह निश्चित रूप से मुझे कुछ सोचने के लिए दिया गया है। मुझे लगता है कि मैं मार्ग से नीचे जाऊंगा जो हाइटचेराइडर ने सुझाव दिया है, जब तक कि मुझे कुछ समस्याएं नहीं आतीं। इसी कारण से मैंने उसका जवाब स्वीकार कर लिया है। – LiamV

6

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

0

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

+1

'वीक रेफरेंस' कचरा संग्रहण समस्या को खत्म कर देगा, लेकिन अगर आपको नोड हटा दिए जाने पर अलग-अलग स्थानों में उचित रूप से डेटा संरचनाओं को अद्यतन करने की आवश्यकता है तो यह समस्या से निपट नहीं पाएगा। –

+0

इसलिए घटनाओं को लागू करें, हटाए गए और पीछे के संदर्भ रखें - इसलिए प्रत्येक नोड को उस शाखा के बारे में पता चल जाएगा जिसमें यह है। –

0

आप निश्चित रूप से प्रत्येक नोड के लिए संदर्भ है कि आप इस उदाहरण

class Branch 
{ 
    public Branch(Node nodeA, Node nodeB) { NodeA = nodeA; NodeB = nodeB; } 
    public Node NodeA { get; set; } 
    public Node NodeB { get; set; } 
} 

class Node 
{ 
    public Node(string name) { Name = name; } 
    public string Name { get; set; } 
} 

तरह हटाने जा रहे हैं, कुछ के लिए अपनी शाखा तत्वों को क्वेरी कर सकते हैं ...

List<Node> nodes = new List<Node>() { new Node("Apple"), new Node("Banana") }; 
List<Branch> branches = new List<Branch>() { new Branch(nodes[0], nodes[1]), new Branch(nodes[1], nodes[0]) }; 

Node node = nodes[0]; 
nodes.Remove(node); 

var query = from branch in branches 
      where branch.NodeA == node || branch.NodeB == node 
      select branch; 

foreach (Branch branch in query) 
{ 
    if (branch.NodeA == node) 
     branch.NodeA = null; 
    if (branch.NodeB == node) // could just be 'else' if NodeA cannot equal NodeB 
     branch.NodeB = null; 
} 

कौन सा में संदर्भ निकाल लिए ठीक है शाखाओं की आपकी सूची। हालांकि, मेहदद बताते हैं कि, यदि आपके नोड ऑब्जेक्ट के संदर्भ अधिक प्रभावशाली हैं तो सभी संदर्भों को मिटा देना अधिक कठिन हो जाता है। ,

public class Node 
{ 
    // Has Some Data! 

    public List<Branch> BranchesIn; 
    public List<Branch> BranchesOut; // assuming this is a directed graph 

    public void Delete() 
    { 
     foreach (var branch in BranchesIn) 
     branch.NodeB.BranchesOut.Remove(branch); 

     foreach (var branch in BranchesOut) 
     branch.NodeA.BranchesIn.Remove(branch); 

     BranchesIn.Clear(); 
     BranchesOut.Clear(); 
    } 
} 

public class Branch 
{ 
    // Contains references to Nodes 
    public Node NodeA 
    public Node NodeB 
} 

अब आप अपने ग्राफ़ वर्ग नोड्स या शाखाओं की एक सूची की जरूरत नहीं है यह सब की जरूरत है एक भी रूट नोड है:

0

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

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