2012-11-10 29 views
6

में विभिन्न LINQ उत्तर निम्नलिखित वीएस 2010 में 2 और वीएस 2012 में 2 के रूप में उत्तर देता है। मुझे व्यक्तिगत रूप से लगता है कि यह होना चाहिए 2. मुझे यकीन नहीं है कि यहां क्या हो रहा है।वीएस 2010 और वीएस 2012

using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System; 

namespace _335ExamPreparation 
{ 
    public class Doubts 
    { 
     int[] nums = { 10, 11, 12, 13, 14, 15, 16 }; 
     int[] divisors = { 7, 10 }; 

     static void Main(string[] args) 
     { 
      Doubts d = new Doubts(); 
      d.func(); 
     } 

     public void func() 
     { 
      var m = Enumerable.Empty<int>(); 
      foreach (int d in divisors) 
      { 
       m = m.Concat(nums.Where(s => (s % d == 0))); 
      } 

      int count = m.Distinct().Count(); 
      Console.WriteLine(count); 
     } 
    } 
} 

धन्यवाद।

+1

रिशेर्पर चेतावनी: संशोधित बंद करने के लिए उपयोग –

उत्तर

16

जो आप देख रहे हैं वह foreach के दो अलग-अलग अनुप्रयोगों का परिणाम है। वीएस 2012 में व्यवहार बदल दिया गया था। this article देखें।

दोनों के बीच अंतर d चर के foreach लूप में दायरे और जीवनकाल शामिल है। वीएस 2012 से पहले, केवल एक d वैरिएबल था, तो इसका मतलब यह है कि आप बंद करने की दो प्रतियां बना रहे हैं (s => (s % d == 0))) जो कि समानd दोनों का संदर्भ देता है। लूप खत्म होने के बाद, d 10 है। जब आप .Distinct().Count() पर कॉल करके क्वेरी निष्पादित करते हैं, तो दोनों बंद होने पर d के लिए 10 का मान दिखाई देगा। यही कारण है कि गिनती वी.एस. पर 1 है 2010

वी.एस. 2012 प्रत्येक यात्रा के लिए एक अलग चर, एक कि है कि विशेष रूप से मेल खाती है उत्पन्न करता है, इसलिए प्रत्येक बंद एक अलगd चर के उदाहरण देखेंगे यात्रा।

यह मोटे तौर पर कोड है कि VS 2010 उत्पन्न करता है:

int d; 
for (int _index = 0; _index < divisors.Length; ++_index) { 
    d = divisors[_index]; 
    m = m.Concat(nums.Where(s => (s % d == 0))); 
} 

और यह मोटे तौर पर क्या वी.एस. 2012 उत्पन्न करता है:

for (int _index = 0; _index < divisors.Length; ++_index) { 
    int d = divisors[_index]; 
    m = m.Concat(nums.Where(s => (s % d == 0))); 
} 

इन दोनों के बीच अंतर तत्काल स्पष्ट होना चाहिए।

आप कोई फर्क नहीं पड़ता कि कौन सा संस्करण वी.एस., तो हमेशा अपने यात्रा चर कॉपी समान व्यवहार प्राप्त करना चाहते हैं:

foreach (int d in divisors) 
{ 
    var copy = d; 
    m = m.Concat(nums.Where(s => (s % copy == 0))); 
} 

तकनीकी तौर पर, केवल तभी यात्रा चर में संदर्भित है एक बंद यदि ऐसा नहीं है तो प्रतिलिपि बनाने की कोई आवश्यकता नहीं है क्योंकि यह वैसे भी बंद करने वाले अर्थशास्त्र को प्रभावित करता है।

+3

+1। अच्छा उत्तर। विस्तृत जानकारी के लिए –

+0

धन्यवाद। संदेह अंदर और बाहर मंजूरी दे दी गई थी। – VVV

+1

@ मिच व्हाट: एक और वोट अच्छा जवाब देने के लिए छोड़ दिया। :) – Neolisk