Псевдоним пространства имен C# - в чем смысл?


Я пытался узнать больше о языке C#, но я не смог увидеть ситуацию, когда можно было бы использовать псевдонимы пространства имен, такие как

 using someOtherName =  System.Timers.Timer;

Мне кажется, что это просто добавит больше путаницы в понимание языка. Может кто-нибудь объяснит, пожалуйста.

спасибо

10 79

10 ответов:

это псевдоним типа, а не псевдоним пространства имен; полезно устранить неоднозначность - например, против:

using WinformTimer = System.Windows.Forms.Timer;
using ThreadingTimer = System.Threading.Timer;

(PS: спасибо за выбор Timer ; - p)

в противном случае, если вы используете оба System.Windows.Forms.Timer и System.Timers.Timer в том же файле вы должны были бы продолжать давать полные имена (так как Timer может быть путаю).

он также играет роль с extern псевдонимы для использования типов с одинаковым полным именем типа из разных сборок-редко, но полезно быть поддержанным.


на самом деле, я вижу еще одно применение: когда вы хотите быстрый доступ к типу, но не хотите использовать обычный using потому что вы не можете импортировать некоторые противоречивые методы расширения... немного запутанно, но ... .. вот вам пример...

namespace RealCode {
    //using Foo; // can't use this - it breaks DoSomething
    using Handy = Foo.Handy;
    using Bar;
    static class Program {
        static void Main() {
            Handy h = new Handy(); // prove available
            string test = "abc";            
            test.DoSomething(); // prove available
        }
    }
}
namespace Foo {
    static class TypeOne {
        public static void DoSomething(this string value) { }
    }
    class Handy {}
}
namespace Bar {
    static class TypeTwo {
        public static void DoSomething(this string value) { }
    }
}

Я использую его, когда у меня есть несколько пространств имен с конфликтующими подпространствами имен и / или именами объектов, вы можете просто сделать что-то вроде [в качестве примера]:

using src = Namespace1.Subspace.DataAccessObjects;
using dst = Namespace2.Subspace.DataAccessObjects;

...

src.DataObject source = new src.DataObject();
dst.DataObject destination = new dst.DataObject();

который в противном случае должен быть написан:

Namespace1.Subspace.DataAccessObjects.DataObject source = 
  new Namespace1.Subspace.DataAccessObjects.DataObject();

Namespace2.Subspace.DataAccessObjects.DataObject dstination = 
  new Namespace2.Subspace.DataAccessObjects.DataObject();

Это экономит кучу текста и может быть использован, чтобы сделать код намного легче читать.

в дополнение к упомянутым примерам, псевдонимы типов (а не псевдонимы пространств имен) могут быть удобны при повторном обращении к универсальным типам:

Dictionary<string, SomeClassWithALongName> foo = new Dictionary<string, SomeClassWithALongName>();

private void DoStuff(Dictionary<string, SomeClassWithALongName> dict) {}

против:

using FooDict = Dictionary<string, SomeClassWithALongName>;

FooDict foo = new FooDict();

private void DoStuff(FooDict dict) {}

Я всегда использую его в таких ситуациях

using Utility = MyBaseNamespace.MySubNamsepace.Utility;

здесь Utility в противном случае будет иметь другой контекст (например,MyBaseNamespace.MySubNamespace.MySubSubNamespace.Utility), но я ожидаю, что/предпочитают Utility чтобы всегда указывать на этот конкретный класс.

лаконичность.

есть льготы, чтобы обеспечить ясность между пространствами имен, которые разделяют имена типов, но по сути это просто сахар.

Это очень полезно, когда у вас есть несколько классов с одинаковым именем в нескольких пространствах имен. Например...

namespace Something.From.SomeCompanyA {
    public class Foo {
        /* ... */
    }
}

namespace CompanyB.Makes.ThisOne {
    public class Foo {
        /* ... */
    }
}

вы можете использовать псевдонимы, чтобы сделать компилятор счастливым и сделать вещи более ясными для вас и других в вашей команде:

using CompanyA = Something.From.CompanyA;
using CompanyB = CompanyB.Makes.ThisOne;

/* ... */

CompanyA.Foo f = new CompanyA.Foo();
CompanyB.Foo x = new CompanyB.Foo();

мы определили псевдонимы пространства имен для всех наших пространств имен. Это позволяет очень легко увидеть, откуда происходит класс, например:

using System.Web.WebControls;
// lots of other using statements

// contains the domain model for project X
using dom = Company.ProjectX.DomainModel; 
// contains common web functionality
using web = Company.Web;
// etc.

и

// User from the domain model
dom.User user = new dom.User(); 
// Data transfer object
dto.User user = new dto.User(); 
// a global helper class
utl.SomeHelper.StaticMethod(); 
// a hyperlink with custom functionality
// (as opposed to System.Web.Controls.HyperLink)
web.HyperLink link = new web.HyperLink(); 

мы определили некоторые рекомендации, как псевдонимы должны быть указаны и все их используют.

в одном смысле это действительно удобно при кодировании в Visual Studio.

Use-case: допустим, я должен использовать только несколько классов, например SqlConnection из пространства имен System.Data. В обычном режиме я буду импортировать System.Data.SqlClient пространство имен в верхней части *.cs файл, как показано ниже:

using System.Data;

теперь посмотрите на мой intellisense. Он сильно распространен с большим количеством классов на выбор при вводе в редакторе кода. Я не собираюсь использовать всю кучу классов на все:

enter image description here

поэтому я предпочел бы использовать псевдоним в верхней части моего *.cs-файл и получить четкое представление intellisense:

using SqlDataCon = System.Data.SqlClient.SqlConnection

теперь посмотрите на мой взгляд intellisense. Это супер-ясно и супер-чистый.

enter image description here

Я нахожу псевдонимы очень полезными в модульном тестировании. При написании модульных тестов, это обычная практика, чтобы объявить тему, чтобы проверить как

MyClass myClassUT;

будучи myClassUT теме Under Test. Но что, если вы хотите использовать статический класс со статическими методами? Затем вы можете создать псевдоним следующим образом:

using MyStaticClassUT = Namespace.MyStaticClass;

тогда вы можете написать свои модульные тесты следующим образом:

public void Test()
{
    var actual = MyStaticClassUT.Method();
    var expected = ...
}

и вы никогда не потеряете из виду что такое испытуемый субъект.

одна из причин, по которой я знаю; это позволяет использовать более короткие имена, когда у вас есть коллизии имен из импортированных пространств имен. Пример:

если вы объявили using System.Windows.Forms; и using System.Windows.Input; в том же файле, когда вы идете в access ModifierKeys вы можете обнаружить, что имя ModifierKeys в обоих System.Windows.Forms.Control и System.Windows.Input пространства имен. Итак, объявив using Input = System.Windows.Input; вы можете узнать System.Windows.Input.ModifierKeys через Input.ModifierKeys.

Я не любитель C#, но пространство имен aliasing кажется мне "лучшей практикой". Таким образом, вы знаете, что вы получаете и все еще не должны печатать слишком много.