2013-01-09 25 views
59

के साथ सी # में नेस्टेड जेनेरिक कक्षाओं को समझना सी # के बारे में एक सहयोगी के साथ बात करते हुए, उसने मुझे कुछ सी # कोड दिखाया जो मुझे आउटपुट की भविष्यवाणी करना पड़ा। यह पहली जगह में आसान लग रहा था, लेकिन यह नहीं था। मैं वास्तव में समझ नहीं सकता कि क्यों सी # इस तरह से कार्य करता है।प्रश्नोत्तरी

कोड:

public class A<T1> 
{ 
    public T1 a; 

    public class B<T2> : A<T2> 
    { 
     public T1 b; 

     public class C<T3> : B<T3> 
     { 
      public T1 c; 
     } 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     A<int>.B<char>.C<bool> o = new A<int>.B<char>.C<bool>(); 

     Console.WriteLine(o.a.GetType()); 
     Console.WriteLine(o.b.GetType()); 
     Console.WriteLine(o.c.GetType()); 

     Console.ReadKey(); 
    } 
} 

उत्पादन होता है:

System.Boolean 
System.Char 
System.Int32 

मुझे सही अगर मैं गलत हूँ, लेकिन मैं समझता हूँ कि o.a प्रकार bool की है, क्योंकि B<T3> और B<T2> inherits से C<T3> inherits A<T2> से। और मैं थोड़ा समझ सकता हूं कि o.c प्रकार int है क्योंकि c का प्रकार T1 है जो इसे बाहरी वर्ग (मुझे लगता है) से मिलता है।

जब मैं यह पता लगाने की कोशिश करता हूं कि o.b टाइप प्रकार का है तो मेरा सिर लगभग विस्फोट कर रहा है। क्या कोई मुझे ये समझा सकता है?

+38

मुझे खुशी है कि मैं आपकी कंपनी में कोड को बनाए नहीं रख रहा हूं। – Default

+0

दिलचस्प, लेकिन व्यावहारिक कुछ भी के लिए कुल ओवरकिल। मुझे लगता है कि यह काम के बजाय अकादमिक है? – JGilmartin

+4

@ डिफॉल्ट क्यों? क्योंकि वे एक दूसरे को अजीब सी # कोड पर प्रश्नोत्तरी करना पसंद करते हैं? – Erix

उत्तर

40

यह एक पुरानी पहेली है, और यह काफी मुश्किल है। जब मैंने इसे एंडर्स को खुद दे दिया तो उसे पहली बार जवाब नहीं मिला!

मुझे लगता है कि संस्करण अपने सहकर्मी दिया आप साइरस के ब्लॉग से है:

http://blogs.msdn.com/b/cyrusn/archive/2005/08/01/446431.aspx

एक थोड़ा सरल संस्करण अपने ब्लॉग पर है।

http://blogs.msdn.com/b/ericlippert/archive/2007/07/27/an-inheritance-puzzle-part-one.aspx

मेरी संस्करण का हल यहाँ है:

http://blogs.msdn.com/b/ericlippert/archive/2007/07/30/an-inheritance-puzzle-part-two.aspx

संक्षेप में, उलझनपूर्ण व्यवहार का कारण है कि आप एक ऐसा नाम है जो दोनों एक बाहरी वर्ग और एक में मौजूद है जब बेस क्लास, बेस क्लास "जीत"। B.X से

public class B 
{ 
    public class X {} 
} 
public class P 
{ 
    public class X 
    { 
    public class D : B 
    { 
     public class N : X {} 
    } 
    } 
} 

फिर P.X.D.N इनहेरिट करती है, नहीं P.X से: यह, अगर आपके पास है। पहेली नेस्टेड जेनेरिक प्रकारों को इस तरह से बना दिया जाता है कि एक ही घोषणा को "बाहरी" और "आधार" खोज पथ दोनों के माध्यम से नामित किया जा सकता है, लेकिन सामान्य निर्माण के कारण अलग-अलग अर्थ हैं।

वैसे भी, ब्लॉग पोस्ट पर स्पष्टीकरण पढ़ें, और यदि यह अभी भी स्पष्ट नहीं है, तो एक और विशिष्ट प्रश्न पूछें।

8

ठीक है, मेरा पहला जवाब गलत था। नेस्टिंग महत्वपूर्ण है:

o.b.GetType() में

ख आसपास के वर्ग जो B<char> जो A<char> जो बारी में टी 1 चार के बराबर बनाता से विरासत के रूप में instantiated है के सदस्य है।

public class A_bool 
{ 
    public bool a; 

    public class B_bool : A_bool 
    { 
     public bool b; 
    } 
} 

public class A_char 
{ 
    public char a; 

    public class B_bool : A_bool 
    { 
     public char b; 
    } 
} 

public class A_int 
{ 
    public int a; 

    public class B_char : A_char 
    { 
     public int b; 

     public class C_bool : A_char.B_bool 
     { 
      public int c; 
     } 
    } 
} 

यहाँ C_bool रूप में अच्छी तरह A_bool.B_bool से प्राप्त किया जा सकता था, है ना: क्या काफी स्पष्ट निम्नलिखित (A_int.B_char.C_bool के लिए मैनुअल इन्स्टेन्शियशन) है नहीं है? लेकिन चूंकि हम A_char में निहित हैं, जिसे पसंद किया गया है।

+1

के रूप में काम करता है तो ओ.यू. बूल क्यों नहीं है? चूंकि सी बी से विरासत में आता है जो बदले में से विरासत में आता है .. –

+1

हां जो भ्रमित है वह विरासत और संलग्न प्रकारों के बीच का अंतर है। 'सी ' बी 'में संलग्न है लेकिन' बी ' – CubeSchrauber

+0

से विरासत विरासत स्थिति को चित्रित करने का एक अच्छा तरीका है! –