Tôi đẩy lùi các câu hỏi "tại sao không" bởi vì đầu tiên, các câu trả lời hầu như không bao giờ thỏa mãn - bạn đã có câu trả lời "tính năng không theo cách bạn muốn vì đặc điểm kỹ thuật không nói những gì bạn muốn nó nói" , mà tôi tưởng tượng không phải là một câu trả lời đặc biệt thỏa mãn. Thứ hai, nhóm thiết kế không cần phải giải thích lý do tại sao thế giới không theo cách bạn muốn; các tính năng không tồn tại miễn phí và sau đó được thiết kế bằng ngôn ngữ; thay vào đó, các tính năng phải được xác minh trước, sau đó được thiết kế trong.
Vì vậy, hãy cố gắng làm cho câu hỏi "tại sao không" của bạn trở nên rõ ràng hơn một chút. Tính năng hiện có là "một bộ khởi tạo mảng có thể được sử dụng (a) ở phía bên phải của dấu bằng trong một lần khởi tạo hoặc (b) ở bên phải của một cấu trúc đối tượng kiểu mảng." Tính năng được đề xuất là: "một trình khởi tạo mảng cũng có thể được sử dụng như một biểu thức". Câu hỏi đặt ra là "Eric sẽ đưa ra những lời chỉ trích nào về tính năng được đề xuất?"
Lời chỉ trích đầu tiên mà tôi đưa ra là không rõ loại biểu thức là gì. Trong bộ khởi tạo biến, bạn có kiểu của biến và trong biểu thức tạo đối tượng, bạn có kiểu của đối tượng; từ cả hai điều này, chúng ta có thể suy ra kiểu của mảng đã xây dựng. Nếu không có một trong hai gợi ý, chúng ta nên suy ra loại nào?
Trong C # 1.0, khi tính năng này được thêm vào, đã có tổng số không các suy luận kiểu 0 được thực hiện bằng ngôn ngữ. Một nguyên tắc thiết kế trong những ngày đầu của C # là "không có gì ngạc nhiên", và trình biên dịch không "quá thông minh". Nếu nhà phát triển dự định một biểu thức thuộc một kiểu cụ thể thì kiểu đó phải rõ ràng theo một cách nào đó trong biểu thức. Khi bạn nói
new double[] { 1, 2, 3.4 }
nó là khá rõ ràng loại nào được dự định. Tương tự
new Animal[] { cat, dog, null }
Tính năng được đề xuất vi phạm nguyên tắc này. Biểu thức phải có một kiểu, nhưng nó không có nghĩa là rõ ràng kiểu của đối số là gì
M({cat, dog, null})
Hơn nữa: Giả sử chúng ta có hai quá tải M, một trong số đó chiếm một mảng Animalvà một nạp một mảng IPet. Quá tải nào củaM được áp dụng? Một trong những chuyển đổi có tốt hơn chuyển đổi khác không? Các loại của các phần tử là Catvà Dog; nó có hợp lý để suy ra một loại thậm chí không xuất hiện ở đó? Đây đều là những câu hỏi mà nhóm thiết kế phải cân nhắc, và đây là những câu hỏi không có câu trả lời rõ ràng. Tính năng được đề xuất dẫn chúng ta vào vùng nước sâu theo thứ tự khá ngắn.
Bây giờ, C # 3.0 giải quyết vấn đề này vì C # 3.0 đã thêm nhiều tính năng mà trình biên dịch thay mặt cho nhà phát triển nhập các loại. Các nguyên tắc trước đây về "không gây ngạc nhiên" và "quy tắc đơn giản" mâu thuẫn với các nguyên tắc thiết kế khác cần thiết để làm cho LINQ hoạt động. Tính năng bạn đề xuất có được thêm vào C # 3.0 không?
Nó có thể đã được. Tính năng thực sự được thêm vào C # 3.0 là:
new[] { x, y, z }
suy ra kiểu của mảng bằng cách sử dụng thuật toán: lấy biểu thức cho các phần tử có kiểu, xác định kiểu nào trong số đó là kiểu tổng quát nhất duy nhất mà tất cả các biểu thức khác có thể chuyển đổi được và nếu kiểu như vậy tồn tại, hãy chọn kiểu đó. Nếu không sẽ tạo ra lỗi,
Tính năng đó có thể đã được nới lỏng hơn nữa để trở thành new[]tùy chọn. Điều này đã không được thực hiện.
Bây giờ, nếu bạn yêu cầu tôi trong khung thời gian C # 3.0 phê bình tính năng được đề xuất, tôi sẽ chỉ ra rằng (1) trình biên dịch C # 3.0 đã có nguy cơ trượt lịch trình cho toàn bộ bản phát hành, vì vậy chúng ta đừng thêm bất kỳ điều gì nữa gánh nặng thiết kế, triển khai và thử nghiệm đối với một tính năng hoàn toàn không cần thiết giúp tiết kiệm cho người dùng sáu lần nhấn phím và (2) C # 3.0 cũng đã thêm các bộ khởi tạo bộ sưu tập:
new List<int>() { 10, 20, 30 }
tại sao {10, 20, 30}tự động phải là một mảng ? Tại sao nó không phải là một List<int>? Hoặc bất kỳ một trong số các loại khác? Tại sao thiên vị đối với mảng? Hãy nhớ rằng, một khi chúng ta chọn lưu trữ cú pháp cho các mảng, chúng ta sẽ bị mắc kẹt với nó mãi mãi . Nó có thể không bao giờ là bất cứ thứ gì khác, vì vậy tính năng được đề xuất không chỉ không cần thiết mà còn ngăn chặn các tính năng có thể có trong tương lai có vẻ hợp lý.
Tóm lại: tính năng được đề xuất đã trực tiếp vi phạm một số nguyên tắc thiết kế của C # 1.0. Nó không thêm gì ngoài gánh nặng không cần thiết cho C # 3.0. Trong tất cả các phiên bản của ngôn ngữ kể từ C # 3.0, tính năng được đề xuất không có lý do chính đáng để khuyên bạn nên dành thời gian, công sức và tiền bạc cho nó thay vì nhiều tính năng khác xứng đáng hơn.
Do đó, không có tính năng như vậy.