Chỉ thị 'sử dụng' nên ở bên trong hay bên ngoài không gian tên?


2062

Tôi đã chạy StyleCop qua một số mã C # và nó tiếp tục báo cáo rằng các lệnh của tôi usingphải nằm trong không gian tên.

Có một lý do kỹ thuật để đưa các usingchỉ thị vào bên trong thay vì bên ngoài không gian tên?


4
Đôi khi nó tạo ra sự khác biệt khi bạn đặt các ứng dụng: stackoverflow.com/questions/292535/linq-to-sql-designer-orms
gius

82
Chỉ để tham khảo, có những hàm ý ngoài câu hỏi về nhiều lớp cho mỗi tệp, vì vậy nếu bạn chưa quen với câu hỏi này, hãy tiếp tục đọc.
Charlie

3
@ user-12506 - điều này không hoạt động tốt trong một nhóm phát triển từ trung bình đến lớn, nơi một số mức độ nhất quán mã được yêu cầu. Và như đã lưu ý trước đây, nếu bạn không hiểu các bố cục khác nhau, bạn có thể tìm thấy các trường hợp cạnh không hoạt động như bạn mong đợi.
benPearce

35
Thuật ngữ: Đó không phải là using tuyên bố ; họ using chỉ thị . Một usingtuyên bố, mặt khác, là một cấu trúc ngôn ngữ mà xảy ra cùng với báo cáo khác bên trong một phương pháp, vv thân Như một ví dụ, using (var e = s.GetEnumerator()) { /* ... */ }là một tuyên bố đó là lỏng lẻo giống như var e = s.GetEnumerator(); try { /* ... */ } finally { if (e != null) { e.Dispose(); } }.
Jeppe Stig Nielsen

1
Nếu điều này chưa được ai đề cập đến, thì thực ra Microsoft cũng khuyên bạn nên đưa các usingtuyên bố vào bên trong các namespacetuyên bố, trong hướng dẫn mã hóa nội bộ
user1451111 27/07/18

Câu trả lời:


2133

Thực sự có một sự khác biệt (tinh tế) giữa hai. Hãy tưởng tượng bạn có đoạn mã sau trong File1.cs:

// File1.cs
using System;
namespace Outer.Inner
{
    class Foo
    {
        static void Bar()
        {
            double d = Math.PI;
        }
    }
}

Bây giờ hãy tưởng tượng rằng ai đó thêm một tệp khác (File2.cs) vào dự án trông như thế này:

// File2.cs
namespace Outer
{
    class Math
    {
    }
}

Trình biên dịch tìm kiếm Outertrước khi xem các lệnh đó usingbên ngoài không gian tên, vì vậy nó tìm thấy Outer.Maththay vì System.Math. Thật không may (hoặc có lẽ may mắn thay?), Outer.MathKhông có PIthành viên, vì vậy File1 hiện đã bị hỏng.

Điều này thay đổi nếu bạn đặt usingbên trong khai báo không gian tên, như sau:

// File1b.cs
namespace Outer.Inner
{
    using System;
    class Foo
    {
        static void Bar()
        {
            double d = Math.PI;
        }
    }
}

Bây giờ trình biên dịch tìm kiếm Systemtrước khi tìm kiếm Outer, tìm thấy System.Math, và tất cả đều tốt.

Một số người sẽ cho rằng đó Mathcó thể là một tên xấu cho một lớp do người dùng định nghĩa, vì đã có một trong đó System; Vấn đề ở đây là chỉ rằng có một sự khác biệt, và nó ảnh hưởng đến khả năng bảo trì của mã của bạn.

Thật thú vị khi lưu ý những gì xảy ra nếu Fooở trong không gian tên Outer, hơn là Outer.Inner. Trong trường hợp đó, việc thêm Outer.Mathvào File2 sẽ phá vỡ File1 bất kể nơi nào usingđi. Điều này ngụ ý rằng trình biên dịch tìm kiếm không gian tên kèm theo trong cùng trước khi nó xem bất kỳ lệnh nào using.


28
Đây là một lý do tốt hơn nhiều để sử dụng các câu lệnh cục bộ so với đối số nhiều không gian tên trong một tệp của Mark. Đặc biệt là sin biên dịch có thể và sẽ phàn nàn về xung đột đặt tên (xem tài liệu StyleCop cho quy tắc này (ví dụ như được đăng bởi Jared)).
David Schmitt

148
Câu trả lời được chấp nhận là tốt, nhưng với tôi có vẻ như là một lý do chính đáng để đặt các mệnh đề sử dụng bên ngoài không gian tên. Nếu tôi ở trong không gian tên Outer.Inner, tôi sẽ mong đợi nó sử dụng lớp Math từ Outer.Inner chứ không phải System.Math.
Frank Wallis

7
Tôi đồng tình với điều này là tốt. Câu trả lời được chấp nhận là chính xác ở chỗ nó mô tả sự khác biệt về mặt kỹ thuật. Tuy nhiên, một hoặc lớp khác sẽ cần một chú thích rõ ràng. Tôi rất muốn Ratehr giải quyết "Toán học" cho lớp cục bộ của riêng tôi và "System.Math" đề cập đến lớp bên ngoài - ngay cả khi System.Math đang được sử dụng làm "Toán học" trước khi Outer.Math tồn tại. Vâng, sẽ có nhiều việc hơn để khắc phục tuy nhiên nhiều tài liệu tham khảo đã có từ trước, nhưng đó cũng có thể là một gợi ý rằng có lẽ Outer.Math nên có một tên khác!
mbmcavoy

13
Câu trả lời tuyệt vời, nhưng dường như với tôi rằng tôi chỉ muốn đặt phi khung sử dụng các câu lệnh cục bộ và giữ cho khung sử dụng các câu lệnh toàn cầu. Bất cứ ai có giải thích thêm tại sao tôi nên thay đổi hoàn toàn sở thích của tôi? Ngoài ra, điều này đến từ đâu, các mẫu trong VS2008 đặt bên ngoài không gian tên?
Thymine

31
Tôi nghĩ rằng đây là một quy ước đặt tên xấu hơn là thay đổi nơi sử dụng của bạn. Không nên có một lớp gọi là Math trong giải pháp của bạn
jDeveloper

454

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 usingchỉ thị cho tất cả các cấp độ này. (Tất nhiên, chúng tôi muốn có usings ở 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:

  1. 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)
  2. Các loại trong không gian tên hiện tại MyCorp.TheProduct.SomeModule.Utilities
  3. Các kiểu trong không gian tên MyCorp.TheProduct.SomeModule
  4. Các loại trong MyCorp.TheProduct
  5. Các loại trong MyCorp
  6. Các kiểu trong không gian tên null (không gian tên toàn cục)
  7. 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:

  1. 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)
  2. Các loại trong không gian tên hiện tại MyCorp.TheProduct.SomeModule.Utilities
  3. Loại trong System, System.Collections.Generic, System.Linq, MyCorp.TheProduct, MyCorp.TheProduct.OtherModule, MyCorp.TheProduct.OtherModule.Integration, vàThirdParty
  4. Các kiểu trong không gian tên MyCorp.TheProduct.SomeModule
  5. Các loại trong MyCorp
  6. 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.TheProductlà 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)].


46
Đây là lời giải thích tốt nhất, bởi vì nó nhấn mạnh thực tế rằng vị trí của các tuyên bố 'sử dụng' là một quyết định có chủ ý từ nhà phát triển. Trong mọi trường hợp, ai đó nên bất cẩn thay đổi vị trí của các tuyên bố 'sử dụng' mà không hiểu ý nghĩa. Do đó, quy tắc StyleCop chỉ là ngu ngốc.
ZunTzu

194

Đặt nó bên trong các không gian tên làm cho các khai báo cục bộ vào không gian tên đó cho tệp (trong trường hợp bạn có nhiều không gian tên trong tệp) nhưng nếu bạn chỉ có một không gian tên cho mỗi tệp thì nó sẽ không có nhiều khác biệt dù chúng có ở bên ngoài hay không bên trong không gian tên.

using ThisNamespace.IsImported.InAllNamespaces.Here;

namespace Namespace1
{ 
   using ThisNamespace.IsImported.InNamespace1.AndNamespace2;

   namespace Namespace2
   { 
      using ThisNamespace.IsImported.InJustNamespace2;
   }       
}

namespace Namespace3
{ 
   using ThisNamespace.IsImported.InJustNamespace3;
}

không gian tên cung cấp một sự phân tách hợp lý, không phải là một (tệp) vật lý.
Jowen

9
Nó không hoàn toàn đúng rằng không có sự khác biệt; usingcác chỉ thị trong namespacecác khối có thể tham chiếu đến các không gian tên tương đối dựa trên namespacekhối kèm theo .
HOẶC Mapper

70
Vâng, tôi biết. chúng tôi đã thiết lập rằng trong câu trả lời được chấp nhận của câu hỏi này năm năm trước.
Đánh dấu Cidade

59

Theo Hanselman - Sử dụng Chỉ thị và Lắp ráp ... và các bài viết khác như vậy về mặt kỹ thuật không có sự khác biệt.

Sở thích của tôi là đặt chúng bên ngoài không gian tên.


3
@Chris M: uh ... liên kết được đăng trong câu trả lời cho thấy không có lợi ích gì so với ngoài, thực sự hiển thị một ví dụ làm sai lệch yêu cầu đưa ra trong liên kết bạn đã đăng ...
johnny

2
Aye tôi đã không đọc đầy đủ các chủ đề nhưng đã mua khi MVPs nói nó đúng. Một anh chàng từ chối nó, giải thích nó và hiển thị mã của anh ta xuống sâu hơn ... "IL mà trình biên dịch C # tạo ra là giống nhau trong cả hai trường hợp. C # ism, và họ không có ý nghĩa cho bản thân NET (không đúng cho việc sử dụng báo cáo nhưng đó là một cái gì đó hoàn toàn khác nhau.)". groups.google.com/group/wpf-disciples/msg/781738deb0a15c46
Chris McKee

84
Vui lòng bao gồm một bản tóm tắt của liên kết. Khi liên kết bị hỏng (vì nó sẽ xảy ra, cho đủ thời gian), đột nhiên một câu trả lời với 32 upvote chỉ có giá trị My style is to put them outside the namespaces.- hầu như không có câu trả lời nào cả.
ANeves

11
Yêu cầu ở đây đơn giản là sai ... có một sự khác biệt về kỹ thuật và trích dẫn của chính bạn nói như vậy ... thực tế, đó là tất cả những gì về nó. Vui lòng xóa câu trả lời sai này ... có nhiều câu trả lời hay và chính xác hơn.
Jim Balter

53

Theo Tài liệu StyleCop:

SA1200: Sử dụngDirectivesMustBePlacesWithinNamespace

Nguyên nhân AC # sử dụng chỉ thị được đặt bên ngoài phần tử không gian tên.

Mô tả quy tắc Vi phạm quy tắc này xảy ra khi chỉ thị sử dụng hoặc chỉ thị sử dụng bí danh được đặt bên ngoài phần tử không gian tên, trừ khi tệp không chứa bất kỳ thành phần không gian tên nào.

Ví dụ: đoạn mã sau sẽ dẫn đến hai hành vi vi phạm quy tắc này.

using System;
using Guid = System.Guid;

namespace Microsoft.Sample
{
    public class Program
    {
    }
}

Tuy nhiên, đoạn mã sau đây sẽ không dẫn đến bất kỳ vi phạm quy tắc nào:

namespace Microsoft.Sample
{
    using System;
    using Guid = System.Guid;

    public class Program
    {
    }
}

Mã này sẽ biên dịch sạch, không có bất kỳ lỗi biên dịch nào. Tuy nhiên, không rõ phiên bản nào của loại Guid đang được phân bổ. Nếu lệnh sử dụng được di chuyển bên trong không gian tên, như hiển thị bên dưới, lỗi trình biên dịch sẽ xảy ra:

namespace Microsoft.Sample
{
    using Guid = System.Guid;
    public class Guid
    {
        public Guid(string s)
        {
        }
    }

    public class Program
    {
        public static void Main(string[] args)
        {
            Guid g = new Guid("hello");
        }
    }
}

Mã không thành công với lỗi trình biên dịch sau, được tìm thấy trên dòng chứa Guid g = new Guid("hello");

CS0576: Không gian tên 'Microsoft.Sample' chứa định nghĩa mâu thuẫn với bí danh 'Hướng dẫn'

Mã này tạo một bí danh cho loại System.Guid được gọi là Guid và cũng tạo ra loại riêng của nó được gọi là Guid với giao diện xây dựng phù hợp. Sau đó, mã tạo một thể hiện của loại Guid. Để tạo phiên bản này, trình biên dịch phải chọn giữa hai định nghĩa khác nhau của Guid. Khi chỉ thị sử dụng bí danh được đặt bên ngoài phần tử không gian tên, trình biên dịch sẽ chọn định nghĩa cục bộ của Hướng dẫn được xác định trong không gian tên cục bộ và bỏ qua hoàn toàn chỉ thị sử dụng bí danh được xác định bên ngoài không gian tên. Thật không may, điều này là không rõ ràng khi đọc mã.

Tuy nhiên, khi chỉ thị sử dụng bí danh được định vị trong không gian tên, trình biên dịch phải chọn giữa hai loại Hướng dẫn xung đột, khác nhau được xác định trong cùng một không gian tên. Cả hai loại này đều cung cấp một hàm tạo phù hợp. Trình biên dịch không thể đưa ra quyết định, vì vậy nó đánh dấu lỗi trình biên dịch.

Đặt chỉ thị sử dụng bí danh bên ngoài không gian tên là một thực tiễn tồi vì nó có thể dẫn đến sự nhầm lẫn trong các tình huống như thế này, trong đó không rõ ràng phiên bản nào của loại thực sự đang được sử dụng. Điều này có khả năng dẫn đến một lỗi có thể khó chẩn đoán.

Việc đặt các chỉ thị sử dụng bí danh trong phần tử không gian tên sẽ loại bỏ điều này như một nguồn lỗi.

  1. Nhiều không gian tên

Đặt nhiều thành phần không gian tên trong một tệp nói chung là một ý tưởng tồi, nhưng nếu và khi điều này được thực hiện, thì nên đặt tất cả các lệnh sử dụng trong mỗi thành phần không gian tên, thay vì trên toàn cầu ở đầu tệp. Điều này sẽ phạm vi không gian tên chặt chẽ, và cũng sẽ giúp tránh các loại hành vi được mô tả ở trên.

Điều quan trọng cần lưu ý là khi mã được viết bằng cách sử dụng các lệnh được đặt bên ngoài không gian tên, cần cẩn thận khi di chuyển các lệnh này trong không gian tên, để đảm bảo rằng điều này không thay đổi ngữ nghĩa của mã. Như đã giải thích ở trên, việc đặt các chỉ thị bí danh trong phần tử không gian tên cho phép trình biên dịch chọn giữa các kiểu xung đột theo cách sẽ không xảy ra khi các lệnh được đặt bên ngoài không gian tên.

Cách khắc phục vi phạm Để khắc phục vi phạm quy tắc này, hãy di chuyển tất cả bằng cách sử dụng các lệnh và chỉ thị sử dụng bí danh trong thành phần không gian tên.


1
@Jared - như tôi đã lưu ý trong câu trả lời của mình, cách giải quyết / giải pháp ưa thích của tôi là chỉ bao giờ có một lớp cho mỗi tệp. Tôi nghĩ rằng đây là một quy ước khá phổ biến.
benPearce

24
Thật vậy, đó cũng là một quy tắc StyleCop! SA1402: Tài liệu AC # chỉ có thể chứa một lớp duy nhất ở cấp gốc trừ khi tất cả các lớp là một phần và cùng loại. Hiển thị một quy tắc bằng cách phá vỡ một quy tắc khác chỉ nhỏ giọt với nước sốt sai.
Nhiệm vụ

6
Được ủng hộ vì là câu trả lời đầu tiên thực sự bao gồm nó từ phối cảnh StyleCop. Cá nhân tôi thích cảm giác trực quan của usings bên ngoài không gian tên. Nội tâm tôi usingtrông thật xấu xí. :)
nawfal

2
Cuối cùng là một câu trả lời tốt cho câu hỏi. Và bình luận của benPearce là không liên quan ... điều này không liên quan gì đến số lượng các lớp trong tệp.
Jim Balter

35

Có một vấn đề với việc đặt sử dụng các câu lệnh bên trong không gian tên khi bạn muốn sử dụng các bí danh. Bí danh không được hưởng lợi từ trước đóusing tuyên bố và phải có đủ điều kiện.

Xem xét:

namespace MyNamespace
{
    using System;
    using MyAlias = System.DateTime;

    class MyClass
    {
    }
}

đấu với:

using System;

namespace MyNamespace
{
    using MyAlias = DateTime;

    class MyClass
    {
    }
}

Điều này có thể được đặc biệt phát âm nếu bạn có một bí danh dài dòng như sau (đó là cách tôi tìm thấy vấn đề):

using MyAlias = Tuple<Expression<Func<DateTime, object>>, Expression<Func<TimeSpan, object>>>;

Với các usingcâu lệnh bên trong không gian tên, nó đột nhiên trở thành:

using MyAlias = System.Tuple<System.Linq.Expressions.Expression<System.Func<System.DateTime, object>>, System.Linq.Expressions.Expression<System.Func<System.TimeSpan, object>>>;

Không đẹp.


1
Bạn classcần một cái tên (định danh). Bạn không thể có một lệnh usingtrong một lớp như bạn chỉ ra. Nó phải ở mức không gian tên, ví dụ bên ngoài lớp ngoài cùng namespacehoặc ngay bên trong cùng namespace(nhưng không nằm trong lớp / giao diện / v.v.).
Jeppe Stig Nielsen

@JeppeStigNielsen Cảm ơn. Tôi đã đặt nhầm các usingchỉ thị. Tôi đã chỉnh sửa nó theo cách tôi dự định. Cảm ơn đã chỉ ra. Lý do vẫn giống nhau, mặc dù.
Neo

4

Như Jeppe Stig Nielsen đã nói , chủ đề này đã có câu trả lời tuyệt vời, nhưng tôi nghĩ rằng sự tinh tế khá rõ ràng này cũng đáng được đề cập.

using các chỉ thị được chỉ định bên trong các không gian tên có thể tạo ra mã ngắn hơn vì chúng không cần phải đủ điều kiện như khi chúng được chỉ định ở bên ngoài.

Ví dụ sau hoạt động vì các loại FooBarcả hai trong cùng một không gian tên toàn cầu , Outer.

Giả sử tệp mã Foo.cs :

namespace Outer.Inner
{
    class Foo { }
}

Bar.cs :

namespace Outer
{
    using Outer.Inner;

    class Bar
    {
        public Foo foo;
    }
}

Điều đó có thể bỏ qua không gian tên bên ngoài trong usingchỉ thị, viết tắt:

namespace Outer
{
    using Inner;

    class Bar
    {
        public Foo foo;
    }
}

8
Đúng là bạn "có thể bỏ qua không gian tên bên ngoài", nhưng điều đó không có nghĩa là bạn nên làm vậy. Đối với tôi, đây là một lập luận khác về lý do tại sao sử dụng các lệnh (không phải là bí danh như trong câu trả lời của @ Neo) nên đi ra ngoài không gian tên, để buộc các tên không gian tên đủ điều kiện.
Keith Robertson

4

Một nếp nhăn tôi gặp phải (không bao gồm trong các câu trả lời khác):

Giả sử bạn có các không gian tên này:

  • Một cái gì đó
  • Phụ huynh. Một cái gì đó. Khác

Khi bạn sử dụng using Something.Other bên ngoài a namespace Parent, nó dùng để chỉ cái đầu tiên (Something.Other).

Tuy nhiên, nếu bạn sử dụng nó bên trong khai báo không gian tên đó, thì nó đề cập đến cái thứ hai (Parent.S Something.Other)!

Có một giải pháp đơn giản: thêm global::tiền tố "": docs

namespace Parent
{
   using global::Something.Other;
   // etc
}

2

Các lý do kỹ thuật được thảo luận trong các câu trả lời và tôi nghĩ rằng cuối cùng nó cũng thuộc về sở thích cá nhân vì sự khác biệt không lớn và có sự đánh đổi cho cả hai. Mẫu mặc định của Visual Studio để tạo .cstệp sử dụng usingcác lệnh bên ngoài không gian tên, ví dụ:

Người ta có thể điều chỉnh stylecop để kiểm tra các usingchỉ thị bên ngoài không gian tên thông qua việc thêm stylecop.jsontệp trong thư mục gốc của tệp dự án bằng cách sau:

{
  "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
    "orderingRules": {
      "usingDirectivesPlacement": "outsideNamespace"
    }
  }
}

Bạn có thể tạo tệp cấu hình này ở cấp độ giải pháp và thêm nó vào các dự án của bạn dưới dạng 'Tệp liên kết hiện có' để chia sẻ cấu hình trên tất cả các dự án của bạn.


2

Một sự tinh tế khác mà tôi không tin đã được bao phủ bởi các câu trả lời khác là khi bạn có một lớp và không gian tên có cùng tên.

Khi bạn có nhập trong không gian tên thì nó sẽ tìm thấy lớp. Nếu quá trình nhập nằm ngoài không gian tên thì việc nhập sẽ bị bỏ qua và lớp và không gian tên phải đủ điều kiện.

//file1.cs
namespace Foo
{
    class Foo
    {
    }
}

//file2.cs
namespace ConsoleApp3
{
    using Foo;
    class Program
    {
        static void Main(string[] args)
        {
            //This will allow you to use the class
            Foo test = new Foo();
        }
    }
}

//file2.cs
using Foo; //Unused and redundant    
namespace Bar
{
    class Bar
    {
        Bar()
        {
            Foo.Foo test = new Foo.Foo();
            Foo test = new Foo(); //will give you an error that a namespace is being used like a class.
        }
    }
}

-8

Đó là một cách thực hành tốt hơn nếu những mặc định sử dụng " tham chiếu " được sử dụng trong giải pháp nguồn của bạn phải nằm ngoài không gian tên và những "tham chiếu được thêm mới" là một cách thực hành tốt là bạn nên đặt nó trong không gian tên. Điều này là để phân biệt những gì tài liệu tham khảo đang được thêm vào.


6
Không, thực sự đó là một ý tưởng tồi. Bạn không nên căn cứ vào vị trí giữa phạm vi địa phương và phạm vi toàn cầu của việc sử dụng các chỉ thị trên thực tế rằng chúng có được thêm mới hay không. Thay vào đó, đó là một thực hành tốt để sắp xếp thứ tự chúng, ngoại trừ các tài liệu tham khảo BCL, nên đi đầu.
Abel
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.