Direktivlərdən istifadə etmək adın daxilində və ya xaricində olmalıdırmı?

StyleCop'u C # kodu üzərindən qaçdım və mənim using direktivlər ad boşluğunun içində olmalıdır.

Adı daxilində və xaricində direktivlər yerləşdirmənin texniki səbəbi varmı?

1827
24 сент. BenPearce tərəfindən təyin Sentyabr 24 2008-09-24 06:49 '08 saat 06:49 'da 2008-09-24 06:49
@ 10 cavab

Həqiqətən, onların arasında (incə) bir fərq var. File1.cs-də aşağıdakı kodunuz olduğunu düşünün:

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

İndi təsəvvür edin ki, kimsə layihəyə (File2.cs) başqa bir fayl əlavə edir:

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

Outer.Math xaricində direktivlər istifadə edənlərə baxmadan əvvəl Outer axtarış Outer.Math , belə ki System.Math yerinə Outer.Math tapır. Təəssüf ki, (və ya bəlkə də xoşbəxtlikdən?), Outer.Math bir PI üzvü yox, File1 artıq işləmir.

Bu kimi using ad boşluğu bəyannaməsini using qoyursanız, bu dəyişəcək:

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

İndi derleyici Xariciyi axtarmadan System üçün axtarır, System.Math tapır və hər şey yaxşıdır.

Bəziləri ki, Math xüsusi bir sinif üçün pis bir ad ola bilər, çünki System ; Əslində bir fərq var və bu kodunuzu saxlamanın asanlığını təsir edir.

Foo , Outer ad boşluğunda deyil, Outer.Inner deyil, nə olacağını da qeyd etmək maraqlıdır. Bu halda, Outer.Math əlavə edərək, Outer.Math using etdiyi yerdən asılı olmayaraq pozur. Bu, kompilyator istənilən using dair göstərişə baxmadan ən kiçik ad boşluğunun axtarışını nəzərdə tutur.

1920
30 сент. Charlie tərəfindən verilmiş cavab Sep 30 2008-09-30 05:33 '08 saat 05:33 'da 2008-09-30 05:33

Bu mövzuya artıq bir neçə əla cavab var, amma bu əlavə cavabla bir az daha ətraflı əlavə edə bilərəm.

Birincisi, məsələn, dövrlər ilə ad boşluğu bəyannaməsini xatırlayın:

 namespace MyCorp.TheProduct.SomeModule.Utilities { ... } 

tam bərabərdir:

 namespace MyCorp { namespace TheProduct { namespace SomeModule { namespace Utilities { ... } } } } 

İstəsəniz, bu səviyyələrdə direktivlər using edə bilərsiniz. (Əlbəttə ki, biz yalnız bir yerdə using etmək istəyirik, lakin dil uyğun olaraq qanuni olacaq.)

Hansı tipin nəzərdə tutulduğunu müəyyən etmək üçün qayda aşağıdakı kimi ifadə edilə bilər: Birincisi, heç bir şey tapmasa, içəriyə uyğun olan "əhatə dairəsini" tapın, növbəti səviyyəyə bir səviyyəyə keçin və tapın və s. bir təsadüf. Hər hansı bir səviyyədə birdən çox matça rast gəlinirsə, növlərdən biri cari məclisdənsə, onu seçin və kompilyator xəbərdarlığı verin. Əks halda buraxın (derleme zamanı hatası).

İndi bu, iki əsas konvensiya ilə konkret bir nümunədə nə deməkdir.

(1) Xaricdə istifadə edildikdə:

 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; } } 

Yuxarıdakı hallarda, hansı növün hansı növün olduğunu bilmək üçün axtarış aşağıdakı qaydada keçir:

  • C içərisində daxil olan daxili növlər (miras alınmış yuvalanmış növlər daxil olmaqla)
  • Mövcud MyCorp.TheProduct.SomeModule.Utilities
  • MyCorp.TheProduct.SomeModule -də növləri
  • MyCorp.TheProduct növləri
  • MyCorp növləri
  • Boş ad boşluqlarında (qlobal ad boşluğu)
  • System növləri, System.Collections.Generic , System.Linq , MyCorp.TheProduct.OtherModule , MyCorp.TheProduct.OtherModule.IntegrationThirdParty
border=0

Digər razılaşma:

(2) Daxildə istifadə edildikdə:

 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; } } 

İndi aşağıda göstərilən qaydada Ambiguous tipə baxın:

  • C içərisində daxil olan daxili növlər (miras alınmış yuvalanmış növlər daxil olmaqla)
  • Mövcud MyCorp.TheProduct.SomeModule.Utilities
  • System , System.Collections.Generic növləri, System.Linq , MyCorp.TheProduct , MyCorp.TheProduct.OtherModule , MyCorp.TheProduct.OtherModule.IntegrationThirdParty
  • MyCorp.TheProduct.SomeModule -də növləri
  • MyCorp növləri
  • Boş ad boşluqlarında (qlobal ad boşluğu)

(Qeyd edin ki, MyCorp.TheProduct "3." hissəsidir və "4." və "5." arasında tələb olunmur).

Son sözlər

Bir ad boşluğu bəyannaməsi içərisində və ya xaricində mesaj qoyub qoymadığınızdan asılı olmayaraq, hər hansı bir şəxsə daha sonra daha yüksək prioritetli adlardan birinə eyni adı olan yeni bir tip əlavə edəcəyi bir şans var.

Bundan əlavə, yuva adının tipi ilə eyni adı varsa, bu problemlərə səbəb ola bilər.

Axtarış bir yerdən digərinə hərəkət etmək həmişə təhlükəlidir, çünki axtarış iyerarxiyası dəyişir və başqa bir növ tapıla bilər. Beləliklə, bir razılaşmanı seçin və heç bir hərəkət etməməyiniz üçün onu dayana.

Visual Studio şablonları adın xaricindəki məlumatları (məsələn, VS yaratdığınız halda, yeni bir faylda yeni bir sinif yaratmaq) xaricində qoyur.

Xarici cihazlardan istifadə [assembly: ComVisible(false)] bir (kiçik) üstünlüyü qlobal bir atribut üçün istifadə qaydalarından istifadə etməkdir, məsələn [assembly: ComVisible(false)] [assembly: System.Runtime.InteropServices.ComVisible(false)] [assembly: ComVisible(false)] yerinə.

374
19 апр. Jeppe Stig Nielsen tərəfindən 19 apreldə cavab verildi 2013-04-19 00:00 '13 'də 0:00' da 2013-04-19 00:00 'da

Ad boşluğuna yerləşdirmək bir fayl üçün bu ad boşluğuna (əgər faylda birdən çox ad boşluğunuz varsa) bildirirsə, ancaq hər bir fayl üçün yalnız bir ad boşluğunuz varsa, onlar çıxdıqları və ya olmadığı ad daxilində.

 using ThisNamespace.IsImported.InAllNamespaces.Here; namespace Namespace1 { using ThisNamespace.IsImported.InNamespace1.AndNamespace2; namespace Namespace2 { using ThisNamespace.IsImported.InJustNamespace2; } } namespace Namespace3 { using ThisNamespace.IsImported.InJustNamespace3; } 
187
24 сент. 24 sentyabrda Mark Cidade tərəfindən verilmiş cavab. 2008-09-24 06:52 '08 saat 06:52 'da 2008-09-24 06:52

Hanselman'a görə - direktiv və məclislərin istifadə edilməsi ilə ... Loading ... və digər oxşar məqalələrdə texniki cəhətdən fərq yoxdur.

Tercihim onları ad boşluklarından kənara qoymaqdır.

58
24 сент. 24 Sentyabrda Quintin Robinson tərəfindən verilmiş cavab 2008-09-24 06:53 '08 saat 06:53 'da 2008-09-24 06:53

StyleCop sənədlərinə görə:

SA1200: istifadə DirectivesMustBePlacedWithinNamespace

Çünki C # direktiv direktivi ad sahəsi elementinin kənarında yerləşdirilir.

Qayda Təsvir Bu qaydanın pozulması, istifadə olunan direktiv və ya istifadə-alias direktivası bir ad sahəsinin elementi xaricində yerləşdirildikdə, faylda ad sahələri elementləri olmadığı halda baş verir.

Məsələn, aşağıdakı kod iki qayda pozuntuuna səbəb olacaq.

 using System; using Guid = System.Guid; namespace Microsoft.Sample { public class Program { } } 

Bununla birlikdə, aşağıdakı kod bu qayda pozuntusuna gətirib çıxarmayacaq:

 namespace Microsoft.Sample { using System; using Guid = System.Guid; public class Program { } } 

Bu kod compiler səhvləri olmadan tərtib olunacaq. Lakin, Guid tipinin hansı versiyası önə çıxır. Istifadə olunan direktiv adın daxilində köçürülsə, aşağıda göstərildiyi kimi, kompilyator səhvi meydana gələcək:

 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"); } } } 

Guid g = new Guid("hello"); olan xəttdə olan aşağıdakı kompilyator səhvləri ilə uğursuz Guid g = new Guid("hello");

CS0576: "Microsoft.Sample" ad sahəsi "Kılavuz" aliasına zidd olan bir tərifi ehtiva edir

Kod, Guid adlı System.Guid tipi üçün bir alias yaradır və həmçinin müvafiq dizayn interfeysi ilə Guid adlı öz növünü yaradır. Kod daha sonra Guid tipli bir nümunə yaradır. Bu nümunəni yaratmaq üçün derivə Guid'in iki fərqli tərifi arasında seçim etməlidir. Istifadə-alias direktivası bir ad sahəsi elementindən kənara qoyulduqda, kompilyator yerli ad boşluğunda müəyyən edilmiş Yerli müəyyən Guid-i seçəcək və adı boşluqdan kənarda müəyyən edilmiş istifadə edərək, direktivi tamamilə görməyəcəkdir. Bu kodu oxuduqda təəssüf ki, aydın deyil.

Bununla yanaşı, istifadə-alias direktivası bir ad boşluğuna yerləşdirildikdə, derleyici eyni ad boşluğunda müəyyən edilmiş iki fərqli ziddiyyətli təlimat növlərini seçməlidir. Bu növlərin hər ikisi bir oyun qurucusunu təmin edir. Derleyici bir qərar qəbul edə bilməz, belə ki bir derleyici səhvini göstərir.

Namizədin xaricindəki bir istifadə-alias direktivinin yerləşdirilməsi pis bir praktikdir, çünki tipin hansı versiyası həqiqətən istifadə edildiyi açıq-aydın olmayan hallarda kafir ola bilər. Bu potensial diaqnoz qoymaq çətin bir səhv gətirə bilər.

Namizəd elementində yalançıları istifadə edərək direktivlərin yerləşdirilməsi bunu səhv mənbəyi kimi aradan qaldırır.

  1. Bir neçə ad boşluqları

Bir neçə ad sahəsi elementini bir faylda yerləşdirmək adətən pis bir fikirdir, ancaq bu iş edildikdə və faylın yuxarı hissəsində deyil, adın bütün elementlərinin hər birindəki istifadə qaydalarını yerləşdirmək məsləhətdir. Bu, ad boşluqlarını əhatə edəcək və yuxarıda təsvir olunan davranışın qarşısını alacaqdır.

Kodun ad boşluğu xaricində yerləşdirilən direktivlərdən istifadə edilməklə yazıldığı zaman, kodun semantikasını dəyişdirməməsini təmin etmək üçün bu adları adda hərəkət edərkən diqqət göstərilməlidir. Yuxarıda qeyd edildiyi kimi, bir ad boşluq elementində istifadə edən direktivlərin yerləşdirilməsi kompilyatorun müddəalar adların kənarında yerləşdirildiyi zaman icra olunmayacaq yollarla ziddiyyətli növlər arasında seçim etməyə imkan verir.

Bu qayda pozuntularını aradan qaldırmaq üçün hər bir şeyi ad və ya digər adları istifadə edərkən direktiv və alias direktivlərindən istifadə edin.

46
14 сент. Cavab JaredCacurak 14 sep tərəfindən verilir . 2009-09-14 18:17 '09 at 6:17 PM 2009-09-14 18:17

Tacirləri istifadə etmək istəyərkən adın içərisində operatorları yerləşdirmə ilə bağlı bir problem var. Ləqəb əvvəlki ifadələrdən using etməməyə yaramır və tam uyğun olmalıdır.

Düşün:

 namespace MyNamespace { using System; using MyAlias = System.DateTime; class MyClass { } } 

qarşı

 using System; namespace MyNamespace { using MyAlias = DateTime; class MyClass { } } 

Uzun bir ləqəb varsa, bu xüsusilə də ifadə edilə bilər, məsələn aşağıdakı (problemi necə tapdım):

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

Bir ad daxilində ifadələr using , birdən-birə çevrilir:

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

Həqiqətən deyil.

31
10 окт. Cavab Neo 10 oct verilir . 2012-10-10 21:47 '12 at 9:47 pm 2012-10-10 21:47

Jeppe Stig Nielsen dediyi kimi, bu mövzu artıq əla cavablar verir, amma düşündüm ki, bu çox aydın incəlik də qeyd etmək lazımdır.

adlar içərisində göstərilən direktivləri using , qısa kod yarada bilərlər, çünki onlar kənarda göstərildikdə tam ixtisaslı olmaq tələb olunmur.

Aşağıdakı nümunə işləyir, çünki FooBar tipləri eyni Outer ad boşluğundadır.

Foo.cs kod faylını verin:

 namespace Outer.Inner { class Foo { } } 

Və Bar.cs:

 namespace Outer { using Outer.Inner; class Bar { public Foo foo; } } 

Bu, using direktivdə xarici ad boşluğunu qısa olaraq atmamalıdır:

 namespace Outer { using Inner; class Bar { public Foo foo; } } 
3
17 сент. Cavab biskvitlərə verilir . 2016-09-17 13:32 '16 saat 13:32 'da 2016-09-17 13:32

Mən inanmadığım bir incəlik eyni adı olan bir sinif və ad boşluğuna sahib olduğunuz halda işin digər cavabları ilə əhatə olundu.

Ad boşluğunda bir idxal olduğunuzda, sinif tapacaqdır. İthalat ad sahəsi xaricindədirsə, idxal edilməyəcək və sinif və ad sahəsi tam olaraq müəyyən edilməlidir.

 //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. } } } 
1
24 авг. 24 Avqustda Ben Gardner tərəfindən verilmiş cavab 2018-08-24 18:28 '18 18:28 'də 2018-08-24 18:28

Cavablarda texniki səbəblər müzakirə edilir və nəticədə fərdi üstünlüklərə gəlir, çünki fərq çox böyük deyil və hər ikisi üçün kompromis var. Məsələn, ad boşluqlarından kənarda direktivlər using .cs faylları yaratmaq üçün standart Visual Studio şablonu

stylecop.json faylını layihə faylının kökünə aşağıdakıları əlavə etməklə ad boşluqlarından kənarda direktivlərdən using etmək üçün stil kağızı konfiqurasiya edə bilərsiniz:

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

Bu konfiqurasiya faylını həll səviyyəsində yarada və bütün layihələrinizlə konfiqurasiya ilə bölüşmək üçün layihələrinizə "Mövcud Link Fayl" kimi əlavə edə bilərsiniz.

0
03 июня '18 в 15:38 2018-06-03 15:38 Cavab satn 03 iyun '18 saat 15:38 2018-06-03 15:38 verilir

Önəmli olanlar , yəni orijinal həllində istifadə edilən "əlaqələr", ad boşluğundan kənarda olmalıdır və "yeni əlavə əlavə" olduqda yaxşı olarsa, yaxşı bir tətbiqdir ki, onu ad boşluğuna yerləşdirin . Bu, hansı əlaqələrin əlavə olunduğu anlamına gəlir.

-8
15 окт. İsrail Ocbina tərəfindən verilmiş cavab 15 oktyabr 2014-10-15 00:30 '14 'də 0:30' da 2014-10-15 00:30

ilə bağlı digər suallar etiketləri və ya bir sual