2017-06-30 9 views
11

Vì C# 7 giới thiệu các bộ giá trị, có một kịch bản có ý nghĩa trong đó chúng phù hợp hơn các bộ dữ liệu không?Có phải C# loại ẩn danh không cần thiết trong C# 7

Ví dụ, dòng sau

collection.Select((x, i) => (x, i)).Where(y => arr[y.i].f(y.x)).ToArray(); 

làm cho các dòng sau

collection.Select((x, i) => new {x, i}).Where(y => arr[y.i].f(y.x)).ToArray(); 

dư thừa.

Trường hợp sử dụng nào được sử dụng tốt hơn trường hợp khác (vì lý do hiệu suất hoặc tối ưu hóa)?

Rõ ràng, nếu có nhu cầu nhiều hơn 6 trường, không thể sử dụng bộ tuples, nhưng có điều gì đó hơi sắc thái hơn không?

+3

Có thể đọc được? 'new {x, i}' làm cho nó hoàn toàn rõ ràng rằng nó là một đối tượng mới đang được trả về, trong khi tôi phải so sánh hai ví dụ để tìm ra cái đầu tiên làm. Nhưng sau đó nó có thể chỉ là tôi. – stybl

+13

Đối với một điều, chúng được hỗ trợ trong cây biểu thức và chữ tuple không phải là ... –

+7

Lưu ý rằng ví dụ của bạn sẽ không biên dịch trong C# 7.0 vì '(x, i)' có các phần tử tuple chưa đặt tên, nhưng chúng được đặt tên ngầm trong C# 7.1. –

Trả lời

12

Có sự khác biệt khác nhau giữa các loại vô danh và C# 7 tuples, mà có thể hoặc không thể thực hiện thêm một phù hợp hơn so với khác trong những tình huống nhất định:

  • C# 7 tuples là ValueTuple<> s. Điều đó có nghĩa là chúng là các loại giá trị trong khi các loại ẩn danh là các loại tham chiếu.
  • Tuples cho phép nhập tĩnh tại thời gian biên dịch vì chúng là loại có thể được biểu thị rõ ràng. Như vậy, bạn có thể sử dụng chúng làm đối số phương thức, loại trả về, v.v.
  • Thành viên của loại ẩn danh là thuộc tính thực tế tồn tại trên loại. Các mục tuple là các trường .
  • Thuộc tính của loại ẩn danh có tên thật, trong khi các trường trên tuple chỉ có tên ItemN (đối với số N). Các nhãn chỉ là thông tin siêu dữ liệu chủ yếu được trình biên dịch sử dụng và không được tiếp tục với đối tượng tuple thực tế.
  • Vì việc tạo một loại vô danh thực sự tạo ra một loại dưới mui xe, bạn có mức độ an toàn với chúng. Vì tuple chỉ là các thùng chứa chung với các đối số kiểu được áp dụng, bạn không có an toàn kiểu đầy đủ với chúng. Ví dụ: một bộ sưu tập (int, int) cho một kích thước sẽ hoàn toàn tương thích với một số (int, int) tuple cho một vị trí , trong khi các loại ẩn danh bị tắt hoàn toàn.
  • Như Jon Skeet đã đề cập, cú pháp tuple C# 7 là currently not supported trong cây biểu thức.
+0

Câu trả lời hay. Bạn sẽ bao gồm điểm của Jon Skeet về các chữ tuple không hoạt động trong các cây biểu thức? –

+0

Tôi thích câu trả lời vì nó cung cấp chi tiết triển khai về 'ValueTuple'. Nhưng nó vẫn không trả lời câu hỏi OP: có những tình huống mà loại ẩn danh tốt hơn 'ValueTuple' không? Điểm 5 (theo như tôi hiểu) là nhiều hơn về việc xem xét sử dụng các loại bình thường thay vì 'ValueTuple'. –

+0

@VadimOvchinnikov Có, tất nhiên là có các kịch bản. Những tình huống mà sự khác biệt giữa hai tính năng này có liên quan. - Nếu bạn cần một ví dụ, hãy [Dapper] (https://github.com/StackExchange/Dapper) nơi bạn có thể chuyển vào một loại ẩn danh với các đối số truy vấn * có tên *. Vì các đối tượng tuple không có tên liên quan, bạn không thể làm điều này với chúng. – poke

1

Câu trả lời hiện tại của @poke là chính xác và ghi chú sự khác biệt giữa các bộ dữ liệu và các loại ẩn danh. Tôi sẽ thảo luận về lý do tại sao bạn vẫn sẽ sử dụng chúng hoặc thích cái khác.

Có hai tính năng C# 7 mới loại bỏ các loại ẩn danh. ValueTuplesRecords.

Lý do chính mà bạn sẽ không sử dụng các loại vô danh là

  • bạn không thể sử dụng các loại vô danh trên toàn cầu và họ chỉ gõ an toàn khi sử dụng tại địa phương.không phải là địa phương, bạn phải coi nó là đối tượng dynamic có chi phí hiệu suất đáng kể

Lý do bạn thích tuple hơn các loại ẩn danh.

  • chúng được nhập an toàn khắp nơi. (bất kể đặt tên)

  • chúng có thể được sử dụng làm đối số phương pháp, nhập đối số, trường và khá nhiều ở mọi nơi. (vâng tôi đã nói khá nhiều, có những nơi cần phải chấp nhận với bộ dữ liệu, vấn đề thời gian của nó.)

  • vì chúng có thể được sử dụng làm đối số kiểu, bạn có thể muốn bọc các thông số nhẹ trong tham số đơn. như Stack<(min, mid, max)>

  • bạn có thể thay đổi mục đặt tên khi đã bao giờ bạn cảm thấy thích hợp của nó, tên bối cảnh chung item có thể đáp ứng và trong bối cảnh cụ thể hơn bạn cần tên cụ thể hơn nữa, như car

  • họ đang ngầm mui trần, int, int có thể được gán cho (int, long) mà không có dàn diễn viên rõ ràng.

  • chúng được sử dụng trong Deconstruct s. mang lại rất nhiều cú pháp cho ngôn ngữ.

  • bạn có thể có nhiều bài tập và tờ khai như (int x, int y) = (0, 1)

Có tất cả các tính năng này, vẫn còn là một trong những lý do mà bạn có thể thích loại vô danh trên tuple.

  • Loại ẩn danh là loại tham chiếu nhưng tuples là loại giá trị.

nhưng nếu bạn muốn sử dụng loại ẩn danh trên toàn cầu thì sao? Bạn thích có các đối tượng động hay các đối tượng được gõ tĩnh?

Tính năng Bản ghi đến lại đánh bại các loại ẩn danh. với các bản ghi bạn xác định lớp của bạn theo cách ngắn gọn, ngắn gọn và thuận tiện. không phải là một thỏa thuận lớn. chỉ một dòng

public class Point(X, Y); 

Nhập toàn bộ địa điểm và bạn cũng có loại tham chiếu trong tay. hai tính năng mới này mang lại mọi thứ để đánh bại các loại vô danh.

Lưu ý rằng Bản ghi chưa được thêm vào, chúng tôi chỉ phải đợi.

Chỉ còn lại sử dụng thực sự của các loại vô danh sẽ

  • họ vẫn phục vụ tính năng tương thích ngược như

  • chúng có thể được sử dụng trong LINQ truy vấn khi bạn sử dụng loại vô danh tại địa phương. do đó tôi không nói các loại vô danh là thừa.

Như tôi đã nói ValueTuples không tương thích với mọi thành phần. nó chỉ là vấn đề thời gian, nhưng đây là cách nó sẽ như thế nào trong tương lai.

đủ đối số. trong sử dụng ý kiến ​​khiêm tốn của tôi về các loại vô danh trở nên hiếm hoi, các lập trình viên cũ vẫn có thể sử dụng kiểu ẩn danh trong LINQ theo thói quen.

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