2012-03-26 30 views
8

Việc triển khai Enumerable.AsEnumerable<T>(this IEnumerable<T> source) chỉ cần trả lại source. Tuy nhiên Observable.AsObservable<T>(this IObservable<T> source) trả lại một AnonymousObservable<T> đăng ký nguồn thay vì chỉ trả về nguồn.Tại sao AsObservable và AsEnumerable được thực hiện khác?

Tôi hiểu các phương pháp này thực sự hữu ích cho việc thay đổi đơn nguyên trong một truy vấn đơn (chuyển từ IQueryable => IEnumerable). Vậy tại sao việc triển khai lại khác nhau?

Phiên bản Observable bảo vệ hơn, trong đó bạn không thể truyền sang một số loại đã biết (nếu bản gốc được triển khai dưới dạng Subject<T> bạn không bao giờ có thể truyền như vậy). Vậy tại sao phiên bản Enumerable không làm điều gì đó tương tự? Nếu loại cơ bản của tôi là List<T> nhưng hiển thị nó là IEnumerable<T> đến AsEnumerable, bạn có thể quay lại List<T>. Xin lưu ý rằng đây không phải là câu hỏi về cách phơi bày IEnumerable<T> mà không có khả năng truyền đến cơ sở, nhưng tại sao việc triển khai giữa EnumerableObservable khác nhau về mặt ngữ nghĩa.

Trả lời

13

Câu hỏi của bạn được trả lời bằng tài liệu mà tôi khuyến khích bạn đọc khi bạn có câu hỏi như vậy.

Mục đích của AsEnumerable là gợi ý cho trình biên dịch "vui lòng ngừng sử dụng IQueryable và bắt đầu xử lý việc này dưới dạng bộ sưu tập trong bộ nhớ".

Như the documentation trạng thái:

Phương pháp AsEnumerable<TSource>(IEnumerable<TSource>) không có tác dụng nào khác ngoài việc thay đổi kiểu thời gian biên dịch nguồn từ một loại mà thực hiện IEnumerable<T>-IEnumerable<T> riêng của mình. AsEnumerable<TSource>(IEnumerable<TSource>) có thể được sử dụng để lựa chọn giữa các triển khai truy vấn khi một chuỗi triển khai IEnumerable<T> nhưng cũng có một bộ phương pháp truy vấn công cộng khác có sẵn.

Nếu bạn muốn ẩn việc thực hiện một chuỗi cơ bản, sử dụng sequence.Select(x=>x) hoặc ToList hoặc ToArray nếu bạn không quan tâm rằng bạn đang thực hiện một chuỗi có thể thay đổi.

Mục đích của AsObservable là để ẩn việc triển khai bộ sưu tập cơ bản. Dưới dạng the documentation nói:

Observable.AsObservable<TSource> ... Ẩn danh tính của chuỗi có thể quan sát được.

Vì hai phương pháp có các mục đích hoàn toàn khác nhau, chúng có các triển khai hoàn toàn khác nhau.

+0

Cảm ơn bạn đã giải thích. Gần đây tôi đã xem một video trên Kênh 9 với Bart De Smet, nơi ông giải thích IQbservable và nó liên quan đến IObservable. Từ cách ông giải thích, nó có vẻ như AsObservable là tương tự như AsEnumerable trong đó bất kỳ hành động quan sát sẽ xảy ra tại địa phương hơn là từ xa. Tôi đã hoàn toàn hiểu nhầm điều này (có lẽ ...), hay chỉ đơn giản là một cách sử dụng khác cho AsObservable? – RichK

+0

Tôi không biết. Tôi khuyên bạn nên hỏi Bart de Smet câu hỏi đó. –

+0

Ok cảm ơn, có lẽ là một ý tưởng hay. Tôi đã đọc tài liệu trước khi hỏi - nhưng sự nhầm lẫn là kết quả của video được đề cập trong bình luận trước của tôi – RichK

9

Bạn đang đúng về mối quan hệ giữa AsEnumerable và AsObservable wrt khía cạnh chuyển đổi từ truy vấn dựa trên biểu thức sang truy vấn trong bộ nhớ.

Đồng thời, phơi bày một chuỗi Rx dựa trên một đề <T> là rất phổ biến, và chúng tôi cần một cách để giấu nó (nếu không thì người dùng có thể đúc để IObservable <T> và tiêm phần tử).

Một thời gian dài trước đây trong lịch sử phát hành trước Rx, chúng tôi đã có một phương pháp ẩn riêng biệt, chỉ đơn thuần là một bí danh Select (x = > x). Chúng tôi không bao giờ thích nó và quyết định có một nơi mà chúng tôi lệch từ LINQ to Objects chính xác, và làm AsObservable đóng vai trò của Hide, cũng dựa trên người dùng tin rằng đây là những gì nó đã làm để bắt đầu.

Lưu ý rằng, chúng tôi cũng có phương pháp mở rộng có tên là AsObservable trên IQbservable <T>. Điều đó không chỉ đơn giản là những gì AsEnumerable làm quá: nó hoạt động như gợi ý cho trình biên dịch để quên về chế độ truy vấn dựa trên biểu thức cây và chuyển sang truy vấn trong bộ nhớ.

+0

Cảm ơn bạn đã xem câu hỏi cũ Bart này, câu trả lời của bạn cung cấp một số thông tin thú vị. – RichK

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