Псевдоним пространства имен C# - в чем смысл?
Я пытался узнать больше о языке C#, но я не смог увидеть ситуацию, когда можно было бы использовать псевдонимы пространства имен, такие как
using someOtherName = System.Timers.Timer;
Мне кажется, что это просто добавит больше путаницы в понимание языка. Может кто-нибудь объяснит, пожалуйста.
спасибо
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. Он сильно распространен с большим количеством классов на выбор при вводе в редакторе кода. Я не собираюсь использовать всю кучу классов на все:
поэтому я предпочел бы использовать псевдоним в верхней части моего *.cs-файл и получить четкое представление intellisense:
using SqlDataCon = System.Data.SqlClient.SqlConnection
теперь посмотрите на мой взгляд intellisense. Это супер-ясно и супер-чистый.
Я нахожу псевдонимы очень полезными в модульном тестировании. При написании модульных тестов, это обычная практика, чтобы объявить тему, чтобы проверить как
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;
в том же файле, когда вы идете в accessModifierKeys
вы можете обнаружить, что имяModifierKeys
в обоихSystem.Windows.Forms.Control
иSystem.Windows.Input
пространства имен. Итак, объявивusing Input = System.Windows.Input;
вы можете узнатьSystem.Windows.Input.ModifierKeys
черезInput.ModifierKeys
.Я не любитель C#, но пространство имен aliasing кажется мне "лучшей практикой". Таким образом, вы знаете, что вы получаете и все еще не должны печатать слишком много.