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


97

Где и когда можно было бы использовать псевдонимы пространства имен, например

 using someOtherName =  System.Timers.Timer;

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


6
Как насчет общесистемной using int = System.Int32в C #? Полезно, правда? Это то же самое использование, которое можно использовать в другом месте.
nawfal

@nawfal Я считаю, что псевдонимы типов не экспортируются. Это означает, что вы не можете определить что-то подобное using int = System.Int32и использовать его в других местах, кроме файла объявления. Так что intдля Int32псевдонима может быть либо достигнуты другими средствами, или специальная вещь в компилятор / выполнения.
KFL

1
@KFL, это правда, но польза от них одинакова.
nawfal

1
@nawfal, о котором вы рассказываете, using int = System.Int32неверен и вводит в заблуждение - это неправильно, потому что intпсевдоним не реализован так, как вы описали. Это вводит в заблуждение, потому что вы подразумеваете, что псевдонимы типов могут использоваться глобально, так же как и как intиспользуется Int32.
KFL

2
@KFL я не имел в виду и то и другое. Я просто сказал, почему может быть полезно иметь собственное имя для типа.
nawfal

Ответы:


152

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

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) { }
    }
}

8
Его можно использовать для псевдонима пространств имен или имен типов.
Шон Брайт

1
@ Шон: да, но приведенный пример относится к типу
Марк Грейвелл

@lupefiasco: удобно из OP выбирать System.Timers.Timer;-p
Марк

Ах, подумал, вы имеете в виду концепцию, а не конкретный пример. Моя вина.
Шон Брайт

26

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

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();

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


17

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

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) {}

8

Краткость.

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


Он четко показывает, какой символ вы используете. Это не просто сахар, это немного многословно (если вы не хотите определять новое имя).
Earth Engine

7

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

using Utility = MyBaseNamespace.MySubNamsepace.Utility;

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


6

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

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();

3

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

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(); 

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


1
Разве вы не замечаете, что часто псевдоним больше связан с контекстом, в котором он используется, чем с физическим расположением объекта?
BenAlabaster 02

2

Я считаю, что псевдонимы очень полезны при модульном тестировании. Когда вы пишете модульные тесты, обычно объявляют объект тестирования как

MyClass myClassUT;

будучи myClassUTв тему U NDER T ЭСТА. Но что , если вы хотите , чтобы единицы записи тестов для статического класса со статическими методами? Затем вы можете создать такой псевдоним:

using MyStaticClassUT = Namespace.MyStaticClass;

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

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

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


2

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

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

using System.Data;

А теперь посмотрите на мой интеллект. Он сильно разросся с множеством классов, из которых можно выбирать при вводе текста в редакторе кода. Я вообще не собираюсь использовать целую кучу классов:

введите описание изображения здесь

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

using SqlDataCon = System.Data.SqlClient.SqlConnection

Теперь посмотрим на мое представление intellisense. Он супер-чистый и супер-чистый.

введите описание изображения здесь


1

Я знаю одну причину; Это позволяет использовать более короткие имена при конфликтах имен из импортированных пространств имен. Пример:

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

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


1

Вы можете использовать их для очень простой модификации кода.

Например:

#if USE_DOUBLES
using BNumber = System.Double;
#else
using BNumber = System.Single;
#endif

public void BNumber DoStuff(BNumber n) {
    // ...
}
public void BNumber DoStuff2(BNumber n) {
    // ...
}
public void BNumber DoStuff3(BNumber n) {
    // ...
}

Путем простого изменения директивы вы можете решить, работает ли весь ваш код в floatили double.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.