Servy trả lời đúng câu hỏi của bạn - một câu hỏi mà bạn đã trả lời cho mình trong một chú thích:
Tôi chỉ nhận ra rằng kể từ khi kiểu trả về là một giao diện, nó sẽ được đóng hộp dù sao, không biết có đúng?
Phải. Câu hỏi tiếp theo của bạn là:
không thể thay đổi phương thức để trả về một điều tra được đánh máy rõ ràng (như List<T>
không)?
Vì vậy, ý tưởng của bạn ở đây là người dùng viết:
IEnumerable<int> Blah() ...
và trình biên dịch thực sự tạo ra một phương thức trả BlahEnumerable
mà là một struct mà thực hiện IEnumerable<int>
, nhưng với sự phù hợp GetEnumerator
vv method và thuộc tính cho phép tính năng "so khớp mẫu" của foreach
để giải phóng quyền anh.
Mặc dù đó là một ý tưởng hợp lý, có những khó khăn nghiêm trọng liên quan khi bạn bắt đầu nói dối về kiểu trả về của một phương thức. Đặc biệt khi nói dối liên quan đến việc thay đổi liệu phương thức trả về một cấu trúc hay một kiểu tham chiếu. Hãy nghĩ đến tất cả những điều không ổn:
Giả sử phương pháp này là ảo. Làm thế nào nó có thể được ghi đè? Kiểu trả về của một phương thức ghi đè ảo phải khớp chính xác với phương thức ghi đè. (Và tương tự cho: phương pháp ghi đè phương pháp khác, phương pháp thực hiện phương thức của giao diện, v.v.)
Giả sử phương pháp được đưa vào đại biểu Func<IEnumerable<int>>
. Func<T>
là covariant trong T
, nhưng hiệp phương sai chỉ áp dụng cho các đối số kiểu của loại tham chiếu.Mã có vẻ như nó trả về một IEnumerable<T>
nhưng trên thực tế nó trả về một kiểu giá trị không tương thích hiệp phương sai với IEnumerable<T>
, chỉ phân bổ tương thích.
Giả sử chúng tôi có void M<T>(T t) where T : class
và chúng tôi gọi M(Blah())
. Chúng tôi hy vọng suy ra rằng T
là IEnumerable<int>
, vượt qua kiểm tra ràng buộc, nhưng loại cấu trúc không không vượt qua kiểm tra ràng buộc.
Và cứ tiếp tục như vậy. Bạn nhanh chóng kết thúc trong một tập phim của Công ty Ba (cậu bé tôi đang hẹn hò với bản thân mình ở đây), nơi một lời nói dối nhỏ kết thúc lên thành một thảm họa lớn. Tất cả điều này để tiết kiệm một lượng nhỏ áp lực thu gom. Không đáng.
Tôi lưu ý rằng mặc dù việc triển khai được tạo bởi trình biên dịch không tiết kiệm áp lực thu thập theo một cách thú vị. Số trước tiên thời gian GetEnumerator
được gọi trên số đếm được trả về, số tự động chuyển số tự động thành một điều tra viên. Lần thứ hai tất nhiên trạng thái là khác nhau để nó phân bổ một đối tượng mới. Vì kịch bản có khả năng là 99,99% là một chuỗi nhất định được liệt kê chính xác một lần, đây là một khoản tiết kiệm lớn đối với áp lực thu thập.
Nguồn
2016-01-13 04:28:52
Tôi chỉ nhận ra rằng vì kiểu trả về là một giao diện ('IEnumerable' hoặc' IEnumerator'), nó [sẽ được đóng hộp] (http://stackoverflow.com/questions/3032750/) anyway, đúng không? Trong trường hợp này, không thể thay đổi phương thức để trả lại một điều tra được đánh máy rõ ràng (như [Danh sách thực hiện] (https://msdn.microsoft.com/en-us/library/b0yss765 (v = vs.110). aspx))? Vì nó thực hiện các giao diện, tất cả các tham chiếu mã đến nó nên được giữ nguyên. (IIRC, điều này hoạt động vì 'foreach' được [phát hiện bằng mẫu] (https://blogs.msdn.microsoft.com/ericlippert/2011/06/30/following-the-pattern/)). –
Lazlo