LINQ tạo ra vấn đề gì?


12

Mỗi lần tôi thấy một câu hỏi được đăng trên Stack Overflow trên C #, tôi thấy ít nhất một hoặc hai câu trả lời được đăng để giải quyết vấn đề với LINQ. Thông thường những người có uy tín rất cao dường như sử dụng LINQ như thuận.

Vì vậy, câu hỏi của tôi là, LINQ có vấn đề gì được sử dụng cho?

Ngoài ra trên các ghi chú bên: Có bất kỳ mục đích nào cần tránh? Có kích thước của tập dữ liệu ảnh hưởng đến hiệu suất của các truy vấn LINQ?




1
LINQ là để truy vấn đồ thị đối tượng. Đó là Language INtegrated Query - nó cho phép bạn truy vấn và thao tác các bộ sưu tập.
Oded

1
đây có lẽ là một câu hỏi có thể đóng lại vì có thể có một câu hỏi hay ẩn giấu trong đó về vấn đề gì linq phù hợp với mặc dù
jk.

1
Linq là khai báo. Bạn nói "những gì" bạn muốn mà không chỉ định "làm thế nào" nó được thực hiện. Đối với linq có nghĩa là bạn có thể sử dụng một truy vấn để nêu những gì bạn muốn. Mã khai báo có thể ngắn hơn và dễ hiểu hơn đối với một số vấn đề.
mike30

Câu trả lời:


16

LINQ được thiết kế chủ yếu để cho phép các truy vấn và chuyển đổi chức năng thuần túy trên các chuỗi dữ liệu (bạn sẽ nhận thấy rằng tất cả các tiện ích mở rộng LINQ có các đại biểu Func nhưng không phải là đại biểu Hành động). Do đó, trường hợp phổ biến nhất của một vòng lặp không phù hợp với LINQ là một trường hợp liên quan đến các tác dụng phụ không thuần túy, vd

foreach(var x in list) Console.WriteLine(x);

Để sử dụng LINQ tốt hơn, chỉ cần thực hành sử dụng nó.

Mỗi khi bạn định viết một forhoặc foreachlặp để làm một cái gì đó với một bộ sưu tập, hãy dừng lại, xem xét liệu nó có phù hợp với LINQ không (nghĩa là nó không chỉ thực hiện một tác động / tác dụng phụ lên các yếu tố), và nếu vậy hãy ép mình viết nó sử dụng LINQ.

Bạn cũng có thể viết foreach phiên bản trước sau đó viết lại thành phiên bản LINQ.

Như Svick chỉ ra, LINQ nên làm cho chương trình của bạn dễ đọc hơn. Nó thường tốt ở chỗ này vì nó có xu hướng nhấn mạnh mục đích của mã hơn là cơ chế; tuy nhiên nếu bạn thấy bạn không thể làm cho các truy vấn của mình dễ đọc hơn một vòng lặp đơn giản, hãy thoải mái gắn bó với vòng lặp đó.

Nếu bạn cần các bài tập để thực hành, hầu hết các bài tập lập trình chức năng sẽ ánh xạ độc đáo đến LINQ, ví dụ 99 vấn đề (đặc biệt là 20 đầu tiên hoặc lâu hơn) hoặc dự án euler .


Tôi có thể phải xóa câu hỏi này ngay bây giờ. Người điều hành nhận xét rằng nó không phù hợp với cộng đồng .. Nếu bạn cảm thấy khác, xin vui lòng cho tôi biết.
user1816120

1
Tôi sẽ thêm rằng nếu bạn viết lại nó vào LINQ và bản gốc vẫn dễ đọc hơn, hãy giữ bản gốc và xóa phiên bản LINQ. Đôi khi, LINQ không thêm bất cứ thứ gì.
Svick

@svick trong lý thuyết có, tôi không chắc tôi có thể nghĩ ra bất kỳ ví dụ nào về việc này không;)
jk.

1
@jk. Ví dụ, đôi khi ReSharper cung cấp để chuyển đổi vòng lặp của tôi sang LINQ bằng cách sử dụng Aggregate(). Tôi nghĩ rằng hầu hết thời gian, vòng lặp là dễ đọc hơn.
Svick

@svick có lẽ là một vấn đề về những gì bạn đã quen, mặc dù tôi sẽ thừa nhận rằng tổng hợp là một tên vụng về cho gấp
jk.

1

Để trả lời câu hỏi đã chỉnh sửa: tóm lại, có ích khi sử dụng LINQ bất cứ khi nào bạn phải thực hiện chức năng "truy vấn" (đó là những gì Q trong LINQ đại diện cho). Xác định một miền chính xác là khó, nhưng nó đơn giản hóa rất nhiều nhiệm vụ liên quan đến trích xuất và thao tác dữ liệu từ các bộ sưu tập.

Để giải thích một chút, rất nhiều chức năng truy vấn đã được đưa trực tiếp vào ngôn ngữ (hay đúng hơn là các trình triển khai LINQ khác nhau), do đó, tất cả những thứ như tổng hợp, đặt hàng, nhóm, lọc, chiếu, tham gia (và nhiều hơn nữa) đều được xử lý cho bạn. Các giải pháp dựa trên LINQ cũng thường ngắn hơn nhiều so với việc bạn thực hiện chúng "bằng tay" và cũng truyền đạt ý định của chúng tốt hơn nhiều.

Một ví dụ đơn giản thường giúp truyền tải sức mạnh của LINQ là hiển thị nội dung của một thư mục, được nhóm theo phần mở rộng. Chạy qua một triển khai bắt buộc điển hình trong đầu của bạn - sẽ có rất nhiều chi tiết thực hiện ngay từ đầu. Có lẽ chúng ta sẽ sử dụng một Dictionary<String, List<String>>để lập chỉ mục các tệp theo phần mở rộng. Tất nhiên, chúng ta sẽ phải kiểm tra xem một khóa đã tồn tại chưa, khởi tạo một danh sách, thêm vào nó, v.v. Nó có thể đi một cái gì đó như:

Dictionary<string, List<string>> fileGroups = new Dictionary<string, List<string>>();

foreach (string file in Directory.GetFiles(Environment.CurrentDirectory))
{
    string extension = Path.GetExtension(file).ToLower();

    if (!fileGroups.ContainsKey(extension))
    {
        fileGroups[extension] = new List<string>();
    }

    fileGroups[extension].Add(file);
}

Hãy xem xét tương đương LINQ:

var query = from file in Directory.GetFiles(Environment.CurrentDirectory)
            group file by Path.GetExtension(file).ToLower();

Lưu ý rằng bản thân truy vấn chỉ có 2 dòng, chắc chắn ngắn hơn bất kỳ giải pháp bắt buộc nào chúng tôi có thể đưa ra. Nó cũng khá dễ đọc; tỷ lệ tín hiệu trên tạp âm cao hơn so với giải pháp đầu tiên. Đối với những người mới sử dụng LINQ, bạn sẽ xuất kết quả của truy vấn đó như sau:

foreach (var fileGroup in query)
{
    Console.WriteLine(String.Format("*** Files with extension: {0}", group.Key));

    foreach (string file in fileGroup)
    {
        Console.WriteLine(file);
    }
}

Với các ví dụ phức tạp hơn, sự khác biệt thường trở nên lớn hơn (ví dụ, chỉ xem xét nhóm theo nhiều trường). Vì vậy, để tóm tắt, LINQ giải quyết nhiều vấn đề truy vấn dữ liệu "hàng ngày" theo cách thường ngắn hơn và tự mô tả nhiều hơn. Điều này có chi phí nhẹ khi phải học cú pháp và công nghệ, nhưng lợi ích vượt xa các tiêu cực.


Bạn có phân loại bản đồ hoặc gấp lại thành "truy vấn" không? Tôi không thực sự nhưng tôi đoán tôi có thể thấy nó có thể .. Tôi thường nghĩ về một tổng hợp là kết quả của một tính toán, không phải là một "truy vấn"
Jimmy Hoffa

@JimmyHoffa Tôi chủ yếu đề cập đến việc áp dụng tính toán cho bộ sưu tập cơ bản, không nhất thiết phải là tính toán. Nhưng có lẽ có những lỗ hổng trong sự tương tự của tôi, nó có nghĩa là minh họa hơn là chính xác 100%.
Daniel B

@JimmyHoffa không, nhưng sau đó tôi không chắc có định nghĩa chặt chẽ nào về việc truy vấn bắt đầu với
jk không.

0

Các ngôn ngữ khác nhau đã được phát triển theo thời gian cho các loại nguồn dữ liệu khác nhau, ví dụ SQL cho cơ sở dữ liệu quan hệ và XQuery cho XML. Do đó, các nhà phát triển đã phải học một ngôn ngữ truy vấn mới cho từng loại nguồn dữ liệu hoặc định dạng dữ liệu mà họ phải hỗ trợ. LINQ đơn giản hóa tình huống này bằng cách cung cấp một mô hình nhất quán để làm việc với dữ liệu trên nhiều loại nguồn và định dạng dữ liệu khác nhau. Trong truy vấn LINQ, bạn luôn làm việc với các đối tượng. để biết thêm truy cập http://msdn.microsoft.com/en-us/l Library / bb39906.aspx


Chính xác LINQ là một API trừu tượng để làm việc với các bộ sưu tập. Một số lợi ích quan trọng: sử dụng C # bạn nhận được STATIC! Xác minh các truy vấn và chuyển đổi của bạn
AndreasScheinert
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.