C# 命名空间别名 - 有啥意义?

Posted

技术标签:

【中文标题】C# 命名空间别名 - 有啥意义?【英文标题】:C# namespace alias - what's the point?C# 命名空间别名 - 有什么意义? 【发布时间】:2010-10-05 01:14:04 【问题描述】:

人们会在何时何地使用命名空间别名

 using someOtherName =  System.Timers.Timer;

在我看来,这只会增加理解语言的困惑。

【问题讨论】:

C# 中的系统范围 using int = System.Int32 怎么样?有用,不是吗?它的用途相同,可以在其他地方利用。 @nawfal 我相信类型别名是不可导出的。这意味着您不能定义像using int = System.Int32 这样的东西,并在声明文件以外的地方使用它。所以这个intInt32 的别名可能是通过其他方式实现的,或者是编译器/运行时的特殊事物。 @KFL 没错,但两者提供的好处是相同的。 @nawfal 您关于using int = System.Int32 的论点既错误又具有误导性——这是错误的,因为int 别名没有按照您描述的方式实现。这是误导性的,因为您暗示可以全局使用类型别名,就像在 Int32 上使用 int 一样。 @KFL 我没有暗示两者。我刚刚说明了为什么为类型设置自定义名称会很有用。 【参考方案1】:

那是类型别名,不是命名空间别名;消除歧义很有用 - 例如,反对:

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

(ps: 感谢您选择Timer ;-p)

否则,如果您在同一个文件中同时使用System.Windows.Forms.TimerSystem.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)  
    

【讨论】:

它可用于命名空间或类型名称的别名。 @Sean: 是的,但是给出的例子是一个类型 @lupefiasco: 方便OP选择System.Timers.Timer ;-p 啊,以为您指的是概念而不是具体示例。过失。【参考方案2】:

当您在多个包含的命名空间中有多个具有相同名称的类时,它非常有用。比如……

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 Utility = MyBaseNamespace.MySubNamsepace.Utility;

Utility 否则会有不同的上下文(如 MyBaseNamespace.MySubNamespace.MySubSubNamespace.Utility),但我希望/更喜欢 Utility 始终指向那个特定的类。

【讨论】:

【参考方案4】:

简洁。

在共享类型名称的命名空间之间提供清晰性有额外的好处,但本质上它只是糖。

【讨论】:

它清楚地显示了您使用的符号。它不仅仅是糖,而且有点冗长(如果你不想定义一个新名称)。【参考方案5】:

当我有多个名称空间具有冲突的子名称空间和/或对象名称时,我会使用它,您可以执行类似 [作为示例] 的操作:

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

它节省了大量的输入,可以用来使代码更容易阅读。

【讨论】:

【参考方案6】:

我们为所有命名空间定义了命名空间别名。这使得很容易看到一个类的来源,例如:

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

我们已经定义了一些如何命名别名以及每个人都在使用它们的准则。

【讨论】:

您是否发现别名通常与使用它的上下文有关,而不是对象的物理位置?【参考方案7】:

除了提到的示例之外,类型别名(而不是命名空间别名)在重复引用泛型类型时会很方便:

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】:

我发现别名在单元测试中非常有用。在编写单元测试时,通常将要测试的主题声明为

MyClass myClassUT;

作为myClassUT 主题Under Test。但是如果你想用静态方法为静态类编写单元测试呢?然后你可以像这样创建一个别名:

using MyStaticClassUT = Namespace.MyStaticClass;

然后你可以这样写你的单元测试:

public void Test()

    var actual = MyStaticClassUT.Method();
    var expected = ...

而且你永远不会忘记测试对象是什么。

【讨论】:

【参考方案9】:

一方面,它在 Visual Studio 中编码时非常方便。

用例:假设我只需要使用几个类,例如SqlConnection 来自命名空间 System.Data。在正常情况下,我将在 *.cs 文件顶部导入 System.Data.SqlClient 命名空间,如下所示:

using System.Data;

现在看看我的智能感知。在代码编辑器中输入时,它大量涌现,有很多类可供选择。我根本不会使用一大堆类:

所以我宁愿在我的 *.cs 文件顶部使用别名并获得清晰的智能感知视图:

using SqlDataCon = System.Data.SqlClient.SqlConnection

现在看看我的智能感知视图。超级清晰,超级干净。

【讨论】:

【参考方案10】:

我知道的一个原因;当您与导入的命名空间发生名称冲突时,它允许您使用较短的名称。 示例:

如果您在访问ModifierKeys 时在同一个文件中声明了using System.Windows.Forms;using System.Windows.Input;,您可能会发现名称ModifierKeysSystem.Windows.Forms.ControlSystem.Windows.Input 命名空间中。 因此,通过声明using Input = System.Windows.Input;,您可以通过Input.ModifierKeys 获得System.Windows.Input.ModifierKeys

我不是 C# 爱好者,但命名空间别名对我来说似乎是“最佳实践”。这样你就知道你得到了什么,并且仍然不必输入太多。

【讨论】:

【参考方案11】:

您可以使用它们非常轻松地修改代码。

例如:

#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 中工作。

【讨论】:

以上是关于C# 命名空间别名 - 有啥意义?的主要内容,如果未能解决你的问题,请参考以下文章

C#中的#代表啥?

C# 命名空间别名限定符 (::) 与取消引用运算符 (.)

PHP命名空间

php命名空间

18PHP 命名空间(namespace)

php之快速入门学习-17(PHP 命名空间)