2010-12-14 16 views
7

मैं एक अजीब मुद्दे पर आया हूं जिसे मैंने अभी देखा है।नेट विरासत - स्वचालित निर्भरता संदर्भ संदर्भ समस्या

यदि आपके पास 3 परियोजनाओं

** नोट चर्चा के बाद संपादित **

परियोजना LIBA के साथ एक समाधान - एक ClassA

namespace LibA 
{ 
    public class ClassA 
    { 
     public override string ToString() 
     { 
      return "The logic in class A!"; 
     } 
    } 
} 

परियोजना LibB है - एक ClassB है

using LibA; 

namespace LibB 
{ 
    public class ClassB 
    { 
     public ClassA a; 

     public ClassB() 
     { 
      a = new ClassA(); 
     } 

     public object Foo() 
     { 
      return a; 
     } 
    } 
} 

प्रोजेक्ट लीबीसी - एक क्लाससी

है
using LibB; 

namespace LibC 
{ 
    public class ClassC 
    { 
     public ClassB b; 

     public ClassC() 
     { 
      b = new ClassB(); 
     } 

     public object Foo() 
     { 
      return b.Foo(); 
     } 
    } 
} 

अंत में एक परीक्षण ड्राइवर

using System; 
using LibC; 

namespace Shell 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      ClassC c = new ClassC(); 
      Console.WriteLine(c.Foo()); 
     } 
    } 
} 

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

पर खींचने की आवश्यकता है, हालांकि, यदि आप क्लास ए को कक्षा ए से प्राप्त करने के लिए बदलते हैं जैसे संकलित करने के लिए

using LibA; 

namespace LibB 
{ 
    public class ClassB : ClassA 
    { 
     ClassA a; 
    } 
} 

प्रयास, आपको त्रुटि

त्रुटि 2 प्रकार 'LibA.ClassA' एक विधानसभा संदर्भित नहीं है में परिभाषित किया गया है मिलेगा। आपको असेंबली 'लीबिया, संस्करण = 1.0.0.0, संस्कृति = तटस्थ, PublicKeyToken = null' का संदर्भ जोड़ना होगा।

** मूल प्रश्न **

किसी को भी पता है क्यों यह बहुत चालाक संदर्भ के लिए LIBA जब ClassA ClassB का एक सदस्य है (चाहे वह MSBuild या दृश्य स्टूडियो है), लेकिन यह करने के लिए पर्याप्त चतुर नहीं है कक्षा ली जब कक्षा कक्षा कक्षा का आधार वर्ग है?

मैं जानता हूँ कि यह nitpicky है, लेकिन मैं वास्तव में कुछ संगत व्यवहार की सराहना करेंगे

** इन मनाया परीक्षणों के साथ संशोधित प्रश्न **

मैं कुछ क्या के रूप में "प्रत्यक्ष" या "अप्रत्यक्ष" को परिभाषित सुनवाई कर रहा हूँ संदर्भ। हालांकि, प्रत्यक्ष रूप से केवल दृश्यता स्कोपिंग नहीं है, यह एक प्रकार का विरासत और वास्तविक उपयोग प्रतीत होता है।

विरासत के बिना, परीक्षण चालक लीग, लीब और लीबसी को हल करने और स्वचालित रूप से संदर्भित करने के लिए पर्याप्त स्मार्ट है।

कक्षा 012 में सार्वजनिक सदस्य वर्ग ए दिखाई देता है और फिर भी अकेले संकलन/लिंकिंग त्रुटि उत्पन्न नहीं करता है।

डीबगर निश्चित रूप से परीक्षण चालक से क्लास को हल करता है, इसलिए यह स्पष्ट रूप से सही असेंबली को लोड करता है।

तो सभी को ध्यान में रखते हुए। मुझे अब पूरी "सीधी" और "अप्रत्यक्ष" चीजें मिलती हैं।

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

+0

दिलचस्प .... +1 – RPM1984

+0

सबसे निश्चित रूप से दिलचस्प। एक पूर्व वीबी.नेट लड़के के रूप में यह कुछ ऐसा है जिसे मैं समझ नहीं सकता। VB.NET संकलक श्रृंखला परियोजना निर्भरताओं के लिए पर्याप्त स्मार्ट है; सी # कंपाइलर क्यों नहीं है? – Crono

उत्तर

0

मैं जानता हूँ कि यह nitpicky है, लेकिन मैं वास्तव में कुछ संगत व्यवहार

यह लगातार है की सराहना करेंगे। आपको किसी भी प्रकार का संदर्भ देना चाहिए जिसका आप सीधे उपयोग करते हैं। अप्रत्यक्ष संदर्भ पारदर्शी रूप से हल किए जाते हैं।

+0

आप अप्रत्यक्ष संदर्भ पर विचार कर रहे हैं? जैसा कि आप कक्षा बी के अपने संशोधन में देख सकते हैं, यह सीधे कक्षा ए – Min

+0

का संदर्भ दे रहा है लेकिन 'कक्षासी' को 'कक्षा' के बारे में पता नहीं है, इसलिए कोई प्रत्यक्ष संदर्भ की आवश्यकता नहीं है। ('कक्षा ए '' कक्षाबी' का एक निजी क्षेत्र है, इस प्रकार 'कक्षासी' के लिए दृश्यमान नहीं है)। – Femaref

4

यह लगातार व्यवहार है। पहला एक साधारण संदर्भ है, दूसरा विरासत है।

एक विधानसभा संकलित किया गया है और एक वर्ग एक और विधानसभा में एक वर्ग से विरासत है, तो उस संदर्भ में यह निर्माण करने के लिए आवश्यक है।

LibB केवल जानकारी है कि ClassB के वर्ग परिभाषा जोड़ा होता है, यह LibA से सब कुछ नकल नहीं करता है (यह, अगर LibA अद्यतन किया जाता है और जब तक कि ऐसा करने ClassA बदल गया है असंगत कोड का उत्पादन होगा LibB अभी भी होगा पुरानी जानकारी है)।

तो LibC में एक विरासत वर्ग परिभाषा का उपयोग करने के लिए, यह (ClassA के लिए) LibA और LibB (ClassB) से दोनों जानकारी का निर्माण करने की जरूरत है, इस प्रकार LibA के लिए एक सीधा संदर्भ की जरूरत है।

उदाहरण में, विभिन्न विधानसभाओं के वर्गों के सभी संदर्भ निजी होते हैं, इस प्रकार केवल अगले स्तर neeed है (ClassCClassA बारे में पता करने के रूप में वहाँ उस वर्ग का कोई प्रत्यक्ष उपयोग है की जरूरत नहीं है)। का उपयोग ClassB में सार्वजनिक क्षेत्र या प्रोपेटी था, ClassC का ClassA का प्रत्यक्ष संदर्भ होगा और उस श्रेणी परिभाषा के प्रत्यक्ष संदर्भ की आवश्यकता होगी (से LibA का संदर्भ)।

एक अलग रूप में, यह भी विरासत उदाहरण में मामला है। ClassC का ClassA (ClassBClassA से विरासत में प्राप्त होने के कारण) का प्रत्यक्ष संदर्भ है, इस प्रकार पूर्ण श्रेणी परिभाषा के निर्माण के लिए घोषित विधानसभा (अर्थात् LibA) का संदर्भ आवश्यक है।

+0

मैं समझता हूं कि विरासत को जानकारी की आवश्यकता क्यों है। मैं सोच रहा हूं कि क्यों लीबसी स्वचालित रूप से लीबिया और लीब दोनों की प्रतिलिपि बनाता है, यदि यह सदस्य है और यदि यह – Min

+0

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

+0

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

0

पहले परिदृश्य में, आप कक्षा का उपयोग कर केवल हैं। इसलिए, इसे रन टाइम पर संकलन समय पर संसाधन की आवश्यकता नहीं है।

दूसरा परिदृश्य में, आप ClassA से इनहेरिट हैं, इसलिए, इसकी परिभाषा और जानकारी आदेश अंतिम संयोजन का निर्माण करने में संकलक द्वारा की जरूरत है।

पहले परिदृश्य में, विजुअलस्टूडियो संदर्भित DLL को आउटपुट निर्देशिका में कॉपी करता है, क्योंकि यह जानता है कि आपको इसकी आवश्यकता होगी।

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

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