2012-11-10 21 views
6

Sau đây là câu trả lời cho 1 trong VS 2010 và 2 trong VS 2012. Cá nhân tôi nghĩ rằng đó là 2. Tôi không chắc chắn những gì đang xảy ra ở đây.Câu trả lời LINQ khác nhau trong VS 2010 và VS 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); 
     } 
    } 
} 

Cảm ơn.

+1

Cảnh báo chia sẻ lại: Truy cập vào đóng cửa đã sửa đổi –

Trả lời

16

Những gì bạn thấy là kết quả của hai ứng dụng khác nhau của foreach. Hành vi đã được thay đổi trong VS 2012. Xem this article.

Sự khác biệt giữa hai yếu tố này liên quan đến phạm vi và tuổi thọ của biến số d trong vòng lặp foreach. Trước năm 2012 VS, chỉ có một biến số d, vì vậy điều này có nghĩa là bạn đang tạo hai bản sao đóng (s => (s % d == 0))) cả hai tham chiếu cùng một sốd. Sau khi kết thúc vòng lặp được đánh giá, d là 10. Khi bạn thực hiện truy vấn bằng cách gọi .Distinct().Count(), cả hai lần đóng sẽ thấy giá trị là 10 cho d. Đây là lý do tại sao số lượng là 1 trên VS 2010.

VS 2012 tạo ra một biến khác nhau cho mỗi lần lặp , vì vậy mỗi việc đóng cửa sẽ thấy một khác nhau dụ của biến d, là tương ứng với đó đặc biệt lặp lại.

Đây là khoảng mã mà VS 2010 tạo:

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

Và đây là khoảng những gì VS 2012 tạo:

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

Sự khác biệt giữa hai nên rõ ràng.

Nếu bạn muốn để có được những hành vi tương tự không có vấn đề mà VS phiên bản, sau đó luôn sao chép biến lặp của bạn:

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

Về mặt kỹ thuật, chỉ khi biến lặp được tham chiếu trong đóng cửa. Nếu không thì không cần phải sao chép vì điều này chỉ ảnh hưởng đến ngữ nghĩa đóng cửa.

+3

+1. câu trả lời hay. –

+0

Cảm ơn thông tin chi tiết về bro. Nghi ngờ đã được xóa trong và ngoài. – VVV

+1

@MitchWheat: một phiếu bầu còn lại để trả lời tốt. :) – Neolisk

Các vấn đề liên quan