Đây là một câu hỏi rất hay, vì tôi đã thấy một số nhà phát triển C ++ viết mã C # khủng.
Tốt nhất không nên nghĩ về C # là "C ++ với cú pháp đẹp hơn". Chúng là những ngôn ngữ khác nhau đòi hỏi cách tiếp cận khác nhau trong suy nghĩ của bạn. C ++ buộc bạn phải liên tục suy nghĩ về những gì CPU và bộ nhớ sẽ làm. C # không như thế. C # đặc biệt được thiết kế để bạn không nghĩ về CPU và bộ nhớ và thay vào đó đang nghĩ về lĩnh vực kinh doanh mà bạn đang viết .
Một ví dụ về điều này mà tôi đã thấy là rất nhiều nhà phát triển C ++ sẽ thích sử dụng cho các vòng lặp vì chúng nhanh hơn so với foreach. Đây thường là một ý tưởng tồi trong C # vì nó hạn chế các loại có thể của bộ sưu tập được lặp đi lặp lại (và do đó khả năng sử dụng lại và tính linh hoạt của mã).
Tôi nghĩ rằng cách tốt nhất để điều chỉnh từ C ++ sang C # là thử và tiếp cận mã hóa từ một góc nhìn khác. Lúc đầu, việc này sẽ khó khăn, vì qua nhiều năm, bạn sẽ hoàn toàn quen với việc sử dụng luồng "CPU và bộ nhớ đang làm gì" trong não để lọc mã bạn viết. Nhưng trong C #, thay vào đó bạn nên suy nghĩ về mối quan hệ giữa các đối tượng trong lĩnh vực kinh doanh. "Tôi muốn làm gì" trái ngược với "máy tính đang làm gì".
Nếu bạn muốn làm một cái gì đó cho mọi thứ trong danh sách các đối tượng, thay vì viết một vòng lặp for trong danh sách, hãy tạo một phương thức lấy IEnumerable<MyObject>
và sử dụng một foreach
vòng lặp.
Ví dụ cụ thể của bạn:
Kiểm soát thời gian tồn tại của tài nguyên yêu cầu dọn dẹp xác định (như tệp). Điều này thật dễ dàng khi sử dụng trong tay nhưng làm thế nào để sử dụng nó đúng cách khi quyền sở hữu tài nguyên đang được chuyển [... betwen thread]? Trong C ++, tôi chỉ cần sử dụng các con trỏ được chia sẻ và để nó xử lý 'bộ sưu tập rác' vào đúng thời điểm.
Bạn không bao giờ nên làm điều này trong C # (đặc biệt là giữa các luồng). Nếu bạn cần làm một cái gì đó cho một tập tin, hãy làm nó ở một nơi cùng một lúc. Sẽ ổn (và thực tế là tốt) để viết một lớp bao bọc quản lý tài nguyên không được quản lý được chuyển qua giữa các lớp của bạn, nhưng đừng thử và chuyển một tệp giữa các luồng và có các lớp riêng biệt viết / đọc / đóng / mở nó. Đừng chia sẻ quyền sở hữu tài nguyên không được quản lý. Sử dụng Dispose
mô hình để đối phó với dọn dẹp.
Liên tục vật lộn với các chức năng ghi đè cho các tổng quát cụ thể (Tôi thích những thứ như chuyên môn mẫu một phần trong C ++). Tôi có nên từ bỏ mọi nỗ lực để thực hiện bất kỳ chương trình chung nào trong C # không? Có lẽ thuốc generic bị hạn chế về mục đích và không phải là C # -ish sử dụng chúng ngoại trừ một miền cụ thể của vấn đề?
Generics trong C # được thiết kế chung chung. Các chuyên ngành của thuốc generic nên được xử lý bởi các lớp dẫn xuất. Tại sao một List<T>
hành vi khác nhau nếu nó là một List<int>
hoặc một List<string>
? Tất cả các hoạt động trên List<T>
là chung chung để áp dụng cho bất kỳ List<T>
. Nếu bạn muốn thay đổi hành vi của .Add
phương thức trên a List<string>
, thì hãy tạo một lớp dẫn xuất MySpecializedStringCollection : List<string>
hoặc một lớp MySpecializedStringCollection : IList<string>
tổng hợp sử dụng chung chung bên trong nhưng thực hiện mọi thứ theo cách khác. Điều này giúp bạn tránh vi phạm Nguyên tắc thay thế Liskov và thực sự lừa đảo những người khác sử dụng lớp học của bạn.
Chức năng giống như macro. Mặc dù nói chung là một ý tưởng tồi, đối với một số miền của các vấn đề không có cách giải quyết nào khác (ví dụ: đánh giá có điều kiện của một tuyên bố, như với các nhật ký chỉ nên chuyển đến các bản phát hành Debug). Không có chúng đồng nghĩa với việc tôi cần đặt thêm nếu (điều kiện) {...} nồi hơi và nó vẫn không bằng về mặt kích hoạt tác dụng phụ.
Như những người khác đã nói, bạn có thể sử dụng các lệnh tiền xử lý để làm điều này. Các thuộc tính thậm chí còn tốt hơn. Trong các thuộc tính chung là cách tốt nhất để xử lý những thứ không phải là chức năng "cốt lõi" cho một lớp.
Nói tóm lại, khi viết C #, hãy nhớ rằng bạn nên suy nghĩ hoàn toàn về lĩnh vực kinh doanh chứ không phải về CPU và bộ nhớ. Bạn có thể tối ưu hóa sau nếu cần , nhưng mã của bạn sẽ phản ánh mối quan hệ giữa các nguyên tắc kinh doanh mà bạn đang cố gắng lập bản đồ.
C#
để tạo mã khác. Bạn có thể đọc mộtCSV
hoặc mộtXML
hoặc những gì bạn đã gửi làm đầu vào và tạo mộtC#
hoặc mộtSQL
tệp. Điều này có thể mạnh hơn so với sử dụng các macro chức năng.