Псевдонім простору імен C # - в чому сенс?


96

Де чи коли можна було б використовувати простір імен, як псевдонім

 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

Відповіді:


151

Це псевдонім типу, а не псевдонім простору імен; корисно роз'єднати - наприклад, проти:

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
Він може використовуватися для псевдонімів або просторів імен, або імен типів.
Шон Брайт, 02

1
@Sean: так, але наведений приклад був для типу
Marc Gravell

@lupefiasco: зручний в ОП вибрати System.Timers.Timer;-p
Marc Gravell

Ах, я думав, ви маєте на увазі поняття, а не конкретний приклад. Mea culpa.
Шон Брайт, 02

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;

де 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;

А тепер подивіться на моє intellisense. Він широко розповсюджений безліччю класів на вибір під час набору тексту в редакторі коду. Я взагалі не збираюся використовувати цілу купу класів:

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

Тому я волів би використовувати псевдонім у верхній частині мого файлу * .cs і отримати чіткий перегляд intellisense:

using SqlDataCon = System.Data.SqlClient.SqlConnection

А тепер подивіться на мій інтелісенсний погляд. Це надзвичайно чітко і надзвичайно чисто.

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


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.