Chủ đề này đã có một số câu trả lời tuyệt vời, nhưng tôi cảm thấy tôi có thể mang lại một chút chi tiết hơn với câu trả lời bổ sung này.
Đầu tiên, hãy nhớ rằng một khai báo không gian tên có dấu chấm, như:
namespace MyCorp.TheProduct.SomeModule.Utilities
{
...
}
hoàn toàn tương đương với:
namespace MyCorp
{
namespace TheProduct
{
namespace SomeModule
{
namespace Utilities
{
...
}
}
}
}
Nếu bạn muốn, bạn có thể đặt using
chỉ thị cho tất cả các cấp độ này. (Tất nhiên, chúng tôi muốn có using
s ở một nơi duy nhất, nhưng nó sẽ hợp pháp theo ngôn ngữ.)
Nguyên tắc giải quyết mà loại được ngụ ý, có thể nói một cách lỏng lẻo như thế này: Đầu tiên tìm kiếm các nội nhất "phạm vi" cho một trận đấu, nếu không có gì được tìm thấy ở đó đi ra ngoài một cấp đến phạm vi tiếp theo và tìm kiếm ở đó, và vân vân , cho đến khi một trận đấu được tìm thấy Nếu ở một mức nào đó, nhiều hơn một kết quả khớp được tìm thấy, nếu một trong các loại là từ hội đồng hiện tại, hãy chọn một trong số đó và đưa ra cảnh báo về trình biên dịch. Nếu không, bỏ (lỗi thời gian biên dịch).
Bây giờ, hãy rõ ràng về ý nghĩa của điều này trong một ví dụ cụ thể với hai quy ước chính.
(1) Với các ứng dụng bên ngoài:
using System;
using System.Collections.Generic;
using System.Linq;
//using MyCorp.TheProduct; <-- uncommenting this would change nothing
using MyCorp.TheProduct.OtherModule;
using MyCorp.TheProduct.OtherModule.Integration;
using ThirdParty;
namespace MyCorp.TheProduct.SomeModule.Utilities
{
class C
{
Ambiguous a;
}
}
Trong trường hợp trên, để tìm hiểu loại nào Ambiguous
, tìm kiếm theo thứ tự sau:
- Các kiểu lồng nhau bên trong
C
(bao gồm các kiểu lồng nhau được kế thừa)
- Các loại trong không gian tên hiện tại
MyCorp.TheProduct.SomeModule.Utilities
- Các kiểu trong không gian tên
MyCorp.TheProduct.SomeModule
- Các loại trong
MyCorp.TheProduct
- Các loại trong
MyCorp
- Các kiểu trong không gian tên null (không gian tên toàn cục)
- Loại trong
System
, System.Collections.Generic
, System.Linq
, MyCorp.TheProduct.OtherModule
, MyCorp.TheProduct.OtherModule.Integration
, vàThirdParty
Các quy ước khác:
(2) Với cách sử dụng bên trong:
namespace MyCorp.TheProduct.SomeModule.Utilities
{
using System;
using System.Collections.Generic;
using System.Linq;
using MyCorp.TheProduct; // MyCorp can be left out; this using is NOT redundant
using MyCorp.TheProduct.OtherModule; // MyCorp.TheProduct can be left out
using MyCorp.TheProduct.OtherModule.Integration; // MyCorp.TheProduct can be left out
using ThirdParty;
class C
{
Ambiguous a;
}
}
Bây giờ, tìm kiếm loại Ambiguous
đi theo thứ tự này:
- Các kiểu lồng nhau bên trong
C
(bao gồm các kiểu lồng nhau được kế thừa)
- Các loại trong không gian tên hiện tại
MyCorp.TheProduct.SomeModule.Utilities
- Loại trong
System
, System.Collections.Generic
, System.Linq
, MyCorp.TheProduct
, MyCorp.TheProduct.OtherModule
, MyCorp.TheProduct.OtherModule.Integration
, vàThirdParty
- Các kiểu trong không gian tên
MyCorp.TheProduct.SomeModule
- Các loại trong
MyCorp
- Các kiểu trong không gian tên null (không gian tên toàn cục)
(Lưu ý rằng đó MyCorp.TheProduct
là một phần của "3." và do đó không cần thiết giữa "4." và "5.".)
Kết luận
Không có vấn đề gì nếu bạn đặt các cách sử dụng bên trong hoặc bên ngoài khai báo không gian tên, luôn có khả năng ai đó sau đó thêm một loại mới có tên giống hệt với một trong các không gian tên có mức độ ưu tiên cao hơn.
Ngoài ra, nếu một không gian tên lồng nhau có cùng tên với một loại, nó có thể gây ra vấn đề.
Luôn luôn nguy hiểm khi di chuyển các cách sử dụng từ vị trí này sang vị trí khác vì hệ thống phân cấp tìm kiếm thay đổi và loại khác có thể được tìm thấy. Do đó, chọn một quy ước và tuân theo nó, để bạn không phải di chuyển.
Theo mặc định, các mẫu của Visual Studio đặt các ứng dụng bên ngoài không gian tên (ví dụ: nếu bạn tạo VS tạo một lớp mới trong một tệp mới).
Một lợi thế (nhỏ) của việc sử dụng bên ngoài là bạn có thể sử dụng các chỉ thị sử dụng cho một thuộc tính toàn cầu, ví dụ [assembly: ComVisible(false)]
thay vì [assembly: System.Runtime.InteropServices.ComVisible(false)]
.