Quy ước đặt tên phương thức C #: ToSomething so với AsSomething


82

Khi tôi đang viết một số phương thức mở rộng cho các đối tượng logic nghiệp vụ của mình, tôi đã đặt ra câu hỏi về việc đổi tên các phương thức chuyển đổi. someObject.ToAnotherObject()sẽ tốt với việc sử dụng rộng rãi object.ToString().

Tuy nhiên, ví dụ như LINQ, kết hợp cả hai biến thể và tôi không thể tìm thấy sự khác biệt giữa chúng. ToDictionary(), ToList(), AsParallel(), AsQueryable(), ...

Sự khác biệt giữa hai quy ước đặt tên này là gì và tôi nên biết những gì để quyết định có sử dụng cho các lớp của riêng mình không?

Câu trả lời:


91

ToDictionaryToListđược đặt trước Tobởi vì chúng không nhất thiết phải bảo tồn bản sắc cấu trúc của bộ sưu tập ban đầu hoặc các đặc tính của nó.

  • Việc chuyển đổi a List<T>thành một Dictionary<K, V>bộ sưu tập có cấu trúc hoàn toàn mới.
  • Việc chuyển đổi a HashSet<T>thành một List<T>sẽ loại bỏ thuộc tính duy nhất của các tập hợp.

Các phương thức có tiền tố là Askhông thực hiện bất kỳ điều nào trong số này - chúng chỉ đơn giản là cung cấp một chế độ xem thay thế cho bộ sưu tập gốc. Họ làm giàu cho nó.


41
Vì vậy, trên một quả táo tôi có thể gọi .AsCleanApple()kể từ khi tôi chỉ cần rửa sạch, và .ToFruitSalad()vì con dao của tôi sẽ thay đổi cấu trúc của apple‽
Physikbuddha

3
@Physikbuddha Về cơ bản, có.
MKII

37
@Physikbuddha Có vẻ như tôi AsCleanApplesẽ thay đổi điều gì đó về quả táo. Một sự tương tự tốt hơn có thể làAsFruit
dcastro

4
.AsCleanAppleSource()sẽ biến một thứ là nguồn cung cấp táo thành nguồn cung cấp táo sạch; Thêm một bước rửa nếu cần thiết nhưng có lẽ không phải làm gì, táo đã được biết là sạch. .ToPunnet()sẽ truy cập nguồn đó và cung cấp cho bạn một punnet táo.
Jon Hanna

2
Điều này không hoàn toàn đúng, nhưng nói chung, bạn có thể coi "AsXXX ()" là một diễn viên và "ToXXX ()" là một chuyển đổi.
nateirvin

26

Trong Linq, ToXXXtất cả các phương thức đều thực thi truy vấn và tạo một đối tượng mới từ kết quả, trong khi các AsXXXphương thức tạo ra một truy vấn mới theo một cách nào đó. Nó có thể là cùng một đối tượng nhưng được truy cập thông qua một giao diện khác ( AsEnumerable()thực hiện điều này) hoặc nó có thể là một đối tượng mới làm thay đổi chức năng (các phương thức khác thực hiện điều này, mặc dù một số kiểm tra xem liệu chúng có thể trả về đối tượng đã cho không, ví dụ: AsQueryable()sẽ trả về sourcenếu nó IQueryable<T>đã được triển khai , hoặc tạo một cái mới EnumerableQuery<TElement>nếu không).


that alters how the functionality- Không howcần thiết hay nên có phần tiếp theo của câu lệnh?
Kapol

@Kapol không, chỉ là lỗi đánh máy do soạn và nhập cùng một lúc.
Jon Hanna

Tôi nghĩ đây là câu trả lời chính xác, tức là một phép chiếu hoạt động so với tĩnh của phiên bản gốc. ToXXX()chiếu dữ liệu không có mối quan hệ với bản gốc. AsXXX()duy trì mối quan hệ hoạt động với bản gốc (ít nhất là trong các ví dụ Có thể đếm được / Có thể truy vấn mà chúng tôi đang thảo luận).
Tim Medora

+1 cho ToXXX execute the queryAsXXX produce a new query. Nghe có vẻ đúng từ những gì tôi đã đọc trên LINQ và MSDN dường như xác nhận cho ToXXX , nhưng tôi đang tự hỏi liệu có ai có nguồn cho liệu tất cả các AsXXX phương pháp có bị hoãn thực thi không?
brichins

1
@brichins thậm chí còn có một cách ý nghĩa để nói "tất cả" vì bất kỳ ai trong chúng ta cũng có thể đi cùng với một nhà cung cấp mới để thêm một nhà cung cấp mới AsXXXlên trên những nhà cung cấp vốn có cho Linq (ví dụ: AsParallelđược thêm bởi PLinq, AsNoTrackingđược cung cấp bởi Entity Framework, và như thế). Chắc chắn, cốt lõi của linq là những gì được định nghĩa bởi QueryableEnumerable, và cả hai lớp đó đều tuân theo quy ước đó. Hầu hết các bổ sung đều đúng, đến mức "tất cả" có thể đúng, nhưng nó quá mở để được đảm bảo luôn đúng (mặc dù tôi sẽ coi bất kỳ sự phá vỡ nào là một lỗ hổng thiết kế).
Jon Hanna
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.