मेरे पास कुछ कक्षाएं हैं जिनमें कई फ़ील्ड हैं। मुझे मूल्य से उनकी तुलना करने की आवश्यकता है, यानी एक वर्ग के दो उदाहरण बराबर हैं यदि उनके फ़ील्ड में एक ही डेटा होता है। मैंने इसके लिए GetHashCode
और Equals
विधियों को ओवरराइड कर दिया है।मूल्य-बराबर और परिपत्र संदर्भ: अनंत रिकर्सन को कैसे हल करें?
ऐसा हो सकता है कि इन वर्गों में परिपत्र संदर्भ शामिल हैं।
उदाहरण: हम संस्थानों (जैसे सरकारी, खेल क्लब, जो कुछ भी) मॉडल करना चाहते हैं। एक संस्थान का नाम है। एक Club
एक संस्था है जिसका नाम और सदस्यों की एक सूची है। प्रत्येक सदस्य Person
है जिसका नाम और पसंदीदा संस्थान है। यदि किसी निश्चित क्लब के सदस्य को यह क्लब अपने पसंदीदा संस्थान के रूप में है, तो हमारे पास एक परिपत्र संदर्भ है।
लेकिन परिपत्र संदर्भ, मूल्य समानता के संयोजन के साथ, अनंत रिकर्सन का कारण बनता है।
interface IInstitution { string Name { get; } }
class Club : IInstitution
{
public string Name { get; set; }
public HashSet<Person> Members { get; set; }
public override int GetHashCode() { return Name.GetHashCode() + Members.Count; }
public override bool Equals(object obj)
{
Club other = obj as Club;
if (other == null)
return false;
return Name.Equals(other.Name) && Members.SetEquals(other.Members);
}
}
class Person
{
public string Name { get; set; }
public IInstitution FavouriteInstitution { get; set; }
public override int GetHashCode() { return Name.GetHashCode(); }
public override bool Equals(object obj)
{
Person other = obj as Person;
if (other == null)
return false;
return Name.Equals(other.Name)
&& FavouriteInstitution.Equals(other.FavouriteInstitution);
}
}
class Program
{
public static void Main()
{
Club c1 = new Club { Name = "myClub", Members = new HashSet<Person>() };
Person p1 = new Person { Name = "Johnny", FavouriteInstitution = c1 }
c1.Members.Add(p1);
Club c2 = new Club { Name = "myClub", Members = new HashSet<Person>() };
Person p2 = new Person { Name = "Johnny", FavouriteInstitution = c2 }
c2.Members.Add(p2);
bool c1_and_c2_equal = c1.Equals(c2); // StackOverflowException!
// c1.Equals(c2) calls Members.SetEquals(other.Members)
// Members.SetEquals(other.Members) calls p1.Equals(p2)
// p1.Equals(p2) calls c1.Equals(c2)
}
}
c1_and_c2_equal
true
लौटना चाहिए, और वास्तव में हम (मनुष्य) देख सकते हैं कि वे मूल्य-बराबर सोच का एक छोटा सा के साथ कर रहे हैं, अनंत प्रत्यावर्तन में चलने के बिना: यहां एक कोड उदाहरण है। हालांकि, मैं वास्तव में यह नहीं कह सकता कि हम इसे कैसे समझते हैं। लेकिन चूंकि यह संभव है, मुझे उम्मीद है कि कोड में इस समस्या को हल करने का एक तरीका भी है!
तो सवाल यह है: मैं असीमित रिकर्सन के बिना मूल्य समानता की जांच कैसे कर सकता हूं?
ध्यान दें कि मुझे सामान्य रूप से परिपत्र संदर्भों को हल करने की आवश्यकता है, न केवल ऊपर से मामला। मैं c1
संदर्भ p1
, और p1
संदर्भ c1
के बाद से इसे 2-सर्कल कहूंगा। अन्य एन-मंडल भी हो सकते हैं, उदा। अगर एक क्लब A
में सदस्य M
है जिसका पसंदीदा क्लब B
है जिसमें सदस्य N
है जिसका पसंदीदा क्लब A
है। यह एक 4-सर्कल होगा। अन्य ऑब्जेक्ट मॉडल एन-सर्कल को विषम संख्याओं के साथ भी अनुमति दे सकते हैं n। मैं इन सभी समस्याओं को एक बार में हल करने का एक तरीका ढूंढ रहा हूं, क्योंकि मुझे पहले से पता नहीं चलेगा कि मूल्य एन क्या हो सकता है।
जैसा कि आपने कहा था, एक्स लम्बाई के सर्कल में एक अनंत रिकर्सन हो सकता है (उदाहरण: 10 पुनरावृत्ति के बाद यह दूसरी स्थिति को इंगित कर रहा है और फिर सर्कल फिर से शुरू होता है)। यदि पुनरावृत्ति नेविगेशन से 1 से 1 तक और 1 से 1 तक नहीं है, तो मैं "विज़िट नोड्स" की एक सूची शामिल करूंगा और सत्यापित कर सकता हूं कि वर्तमान वाला पहले ही संसाधित हो गया है, यदि हां, तो वापसी करें। – Dryadwoods
उपरोक्त सुझाव दिया गया है कि पहले से परीक्षण/कॉल किए गए संदर्भ के लिए हैशसेट या कुछ पास रखें। यह एक वैकल्पिक तर्क हो सकता है जो शून्य पर सेट हो जाता है जो पहले कॉल या कुछ के बाद बनाया और पारित हो जाता है। – Rob
मेरे opionion में आपके 'बराबर' कार्यान्वयन बहुत सख्त हैं। दो व्यक्तियों के बराबर बराबर क्यों हैं यदि उनके पास एक ही पसंदीदा संस्थान है? यदि वह इस सप्ताह के अंत में एक नए क्लब में जाता है तो एक व्यक्ति अलग क्यों होता है? एक 'आईडी' संपत्ति –