Là loại làm tổ được coi là thực hành xấu?


8

Như đã lưu ý bởi tiêu đề, các kiểu lồng nhau (ví dụ như các kiểu hoặc cấu trúc liệt kê trong một lớp) có được coi là thực hành xấu hay không? Khi bạn chạy Phân tích mã trong Visual Studio, nó sẽ trả về thông báo sau có nghĩa là:

Cảnh báo 34 CA1034: Microsoft.Thiết kế: Không lồng loại 'ClassName.SturationueName'. Ngoài ra, thay đổi khả năng truy cập của nó để nó không thể nhìn thấy bên ngoài.

Tuy nhiên, khi tôi làm theo khuyến nghị của Phân tích mã, tôi thấy rằng có xu hướng có rất nhiều cấu trúc và kiểu liệt kê trôi nổi trong ứng dụng chỉ có thể áp dụng cho một lớp duy nhất hoặc sẽ chỉ được sử dụng với lớp đó. Như vậy, nó có thích hợp để lồng loại tội lỗi đó không, hay có cách nào tốt hơn để làm điều đó?


Câu hỏi này RẤT liên quan chặt chẽ đến các lập trình viên.stackexchange.com/questions/34067 Tôi không biết có nên đóng cái này lại như một bản sao không ...
Walter

@Walter - Họ rất thân thiết nhưng tôi đã nghe câu hỏi được đưa ra riêng cho các lớp lồng nhau trong các lớp và lồng tất cả các loại khác trong các lớp riêng biệt để nó không bị tổn thương. Hóa ra, tôi đã không tìm thấy câu hỏi đó khi tôi thực hiện tìm kiếm ban đầu.
rjzii

Câu trả lời:


15

Các loại lồng nhau không xấu. Cảnh báo bạn đang nhận không cho thấy bạn không bao giờ có loại lồng nhau. Nó chỉ đơn giản chỉ ra rằng loại lồng nhau của bạn nên sử dụng một công cụ sửa đổi truy cập và vị trí mã thích hợp.

Nếu loại lồng thực sự chỉ được sử dụng bên trong lớp chứa (tức là nó là một bộ chứa dữ liệu nội bộ hoặc chỉ báo trạng thái), thì hãy đặt bộ sửa đổi truy cập của nó thành riêng tư.

Nếu kiểu lồng nhau là một phần của một hoặc nhiều chữ ký phương thức, thì thực tế nó không phải là cục bộ của lớp chứa. Nó đại diện cho một thông điệp được truyền đến hoặc từ các thể hiện của lớp chứa. Trong trường hợp này, tốt hơn hết là nên di chuyển kiểu lồng nhau ra khỏi lớp chứa và cung cấp cho nó một công cụ sửa đổi truy cập mở hơn như nội bộ hoặc công khai.

Nói tóm lại, cảnh báo dường như khuyến nghị rằng bạn đặt các loại cục bộ ở chế độ riêng tư và các loại được chia sẻ nên đứng độc lập.


Công cụ sửa đổi nội bộ là những gì tôi đã làm trong hầu hết các trường hợp, dọn dẹp mọi thứ một chút, nhưng có rất nhiều trong số chúng nổi xung quanh trong ứng dụng.
rjzii

1

Nếu nó chỉ được sử dụng bởi lớp đó thì nó sẽ được đặt ở chế độ riêng tư và đó chính xác là những gì mà thông điệp đang gợi ý.


Trong một số trường hợp được thực hiện, nhưng trong các trường hợp khác, một kiểu liệt kê đang được sử dụng trong các lệnh gọi phương thức được đính kèm với lớp. Tương tự, tôi cũng đã thấy các cấu trúc được sử dụng cho lớp phương thức nếu số lượng tham số vượt quá một số lượng nhất định.
rjzii

0

Cảnh báo về các kiểu lồng nhau là một trong những "gợi ý" đầu tiên tôi nhận được một thời gian sau khi kích hoạt Phân tích mã. Đó cũng là lý do tại sao tôi tắt nó đi.

Một số gợi ý thực sự xa lạ như thể chúng đến từ hành tinh khác.

Tôi đặt phép liệt kê trong các lớp để giữ mọi thứ hợp lý với nhau.

Hãy nghĩ về nó theo cách này: nếu các kiểu lồng nhau sẽ là tội ác tuyệt đối trong mọi trường hợp, tại sao các nhà thiết kế ngôn ngữ sẽ thực hiện nó ngay từ đầu? Bởi vì nó hữu ích trong nhiều trường hợp và trong vấn đề đó, cảnh báo đã nói chỉ đơn thuần là chỉ ra rằng một cái gì đó trong mã của bạn có thể không tối ưu. Nếu nó áp dụng hay không là tùy thuộc vào bạn để quyết định.


2
Một không gian tên phải là nhóm hợp lý của bạn cho enum; không phải lớp học
Aaron McIver

1
Vâng trong một số tình huống tôi thấy nó bất tiện.

Nếu bạn hiện đang đặt enum trong lớp, việc di chuyển nó ra ngoài lớp để nó nằm trong không gian tên sẽ lấy tất cả CTRL + X kết hợp với CTRL + V ... không chắc nó sẽ trở nên bất tiện như thế nào?
Aaron McIver

Đôi khi tôi đặt enum của tôi trong các lớp học. Tôi nghĩ rằng có những lý do chính đáng cho nó - đó không phải là một quy tắc nghiêm ngặt.
Không ai là

3
@rmx Tôi chưa bao giờ sử dụng enum trong một lớp duy nhất; nó luôn được sử dụng trong nhiều lớp, vì vậy việc định nghĩa nó trong không gian tên là thực thể của chính nó có ý nghĩa hơn nhiều.
Aaron McIver

0

Không

Một ví dụ điển hình trong C # là IEnumerable khi các lớp khác không cần biết chính xác lớp mà nó trả về, chỉ có điều nó là IEnumerator. Vì vậy, thật hợp lý khi biến nó thành một lớp lồng nhau nếu không bạn có thể có rất nhiều lớp nhỏ trôi nổi trong intellisense thực hiện IEnumerator


Trong một số trường hợp, hiệu quả thời gian chạy có thể được cải thiện nếu trình biên dịch biết loại được trả về bởi GetEnumerator(); Vì lý do đó, List<T>.GetEnumerator()trả lại List<T>.Enumerator(). Nếu đã có một cách nào đó để yêu cầu trình biên dịch sử dụng một số phương thức được đặt tên khác, thì có lẽ tốt hơn là có phương thức đó, ví dụ như ForEachGetEnumerator()trả về List<T>.EnumeratorGetEnumerator()trả về IEnumerator<T>, nhưng không có cơ chế nào tồn tại cho điều đó.
supercat
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.