2015-10-16 15 views
9

का उपयोग कर रहा 3 सी # परियोजनाओं/विधानसभाओं, ए, बी और सी बी ए का संदर्भ मिल गया है, सी का संदर्भ बीसंदर्भ केवल आवश्यक त्रुटि LINQ

एक में:

using System.Collections.Generic; 

namespace A 
{ 
    public class Dict : Dictionary<string, object> {} 
    public class Options: Dict {} 
} 

बी में :

using System.Collections.Generic; 
using A; 

namespace B 
{ 
    public class Client 
    { 
     public void M(IDictionary<string, string> d) 
     { 
      var dict = d.ToDict<Options>(); 
     } 
    } 

    public static class Extensions 
    { 
     public static T ToDict<T>(this IDictionary<string, string> dictionary) 
      where T : Dict, new() 
     { 
      return new T(); 
     } 
    } 
} 

सी में:

using System.Collections.Generic; 
using B; 

namespace C 
{ 
    public class Worker 
    { 
     public void M() 
     { 
      var client = new Client(); 
      var d = new Dictionary<string, string> { { "k", "v" } }; 
      var strings = new [] { "one", "two" }; // never used 
      client.M(d); 
     } 
    } 
} 

यह सब सह mpiles।

The type 'A.Dict' is defined in an assembly that is not referenced. You must add a reference to assembly 'A, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.

Extensions वर्ग internal बनाना या चलती:

अगर मैं परियोजना सी में System.Linq नाम स्थान आयात और client.M() को कॉल करने से पहले लाइन strings.Select(s => s); (या किसी भी LINQ विधि) जोड़ने के लिए, मैं एक संकलक त्रुटि मिलती है यह एक अलग नामस्थान में त्रुटि को रोकता है।

चूंकि बी को ए को लपेटने और सी से अपने विवरण छिपाने के लिए माना जाता है, तो विस्तार विधि को सार्वजनिक होने देना गलत है। लेकिन मुझे समझ में नहीं आ रहा है कि LINQ लाए जाने पर इसे केवल कंपाइलर द्वारा क्यों चुना जाता है।

क्या कम से कम एक एक्सटेंशन विधि की उपस्थिति संकलक को थोड़ा अलग व्यवहार करने का कारण बनती है?

+1

3.5 से 4.6 – SWeko

+0

@SWeko से लक्ष्य ढांचे का उपयोग करके इसे VS2015 में पुन: उत्पन्न करने में असमर्थ: निर्भरता को हल करते समय मुझे कई मामलों का सामना करना पड़ा, जब Roslyn स्मार्ट है। वास्तव में, VS2015 का उपयोग करके सफलतापूर्वक संकलित एक ही प्रोजेक्ट विफल रहता है और VS2013 या इससे पहले का संकलन करते समय अतिरिक्त असेंबली संदर्भ की आवश्यकता होती है। – Dennis

+0

@SWeko धन्यवाद, मैं उल्लेख करना भूल गया कि मैं वीएस2013 का उपयोग कर रहा हूं। मैंने एक टैग जोड़ा है। –

उत्तर

2

कोई भी अनसुलझे विधि जोड़ना इस त्रुटि को ट्रिगर करेगा।

मुझे याद नहीं है कि मैं इसे कहां पढ़ता हूं, लेकिन सी # (वीएस2013) कंपाइलर मिलान विधि को हल करने से रोक देगा जब यह मेल खाने वाली गैर-एक्सटेंशन विधि पाता है। आप प्रोजेक्ट सी में निम्नलिखित कोड जोड़कर इसे सत्यापित कर सकते हैं।

public static class Extensions 
{ 
    public static void M(this Client c, IDictionary<string, string> d) 
    { 
     return; 
    } 
} 

इससे कोई त्रुटि नहीं आती है!

जब कोई विधि गैर-विस्तार विधि के साथ हल नहीं होती है (उदाहरण के लिए, संकलक त्रुटि के कारण "abc".Foo() जोड़ें), अब सी # कंपाइलर विस्तार विधियों को स्कैन करना शुरू कर देता है। जब यह B.Extensions.ToDict स्कैन करता है, तो यह नहीं पता कि Dict क्या है। हालांकि, असेंबली बी के मेटाडाटा ने इसे A.Dict से कंपाइलर बताया, फिर आपको त्रुटि दिखाई देती है।

+0

ठीक से पुन: उत्पन्न किया गया, धन्यवाद। अजीब लगता है कि संकलक भी एक पूरी तरह से अलग नाम के साथ एक विधि में बहुत गहराई से देखकर परेशान करता है, लेकिन हो सकता है कि यह सभी एक्सटेंशन विधियों का कैश बनाता है जो कुछ मिल सकता है या ऐसा कुछ भी हो सकता है। –

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