C#名称空间别名-重点是什么?


95

人们将在何时何地使用名称空间别名

 using someOtherName =  System.Timers.Timer;

在我看来,这只会增加对语言的理解的混乱。


6
整个using int = System.Int32C#中的系统如何?有用,不是吗?它具有与其他地方相同的用途。
2013年

@nawfal我相信类型别名是不可导出的。意味着您不能定义类似的内容using int = System.Int32,而不能在声明文件之外的其他地方使用它。因此,这intInt32别名可通过一些其他手段来实现,或者是在编译/运行时特别的东西。
KFL

1
@KFL是正确的,但是两者提供的好处具有相同的性质。
nawfal

1
@nawfal有关您的论点using int = System.Int32既错误又具有误导性-这是错误的,因为int没有按照您的描述方式实现别名。这具有误导性,因为您暗示类型别名可以像全局使用一样int使用Int32
KFL

2
@ KFL我没有暗示。我只是说了为什么为类型使用自定义名称会很有用。
nawfal

Answers:


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
它可以用作名称空间或类型名称的别名。
肖恩·布莱特

1
@Sean:是的,但是给出的例子是一种类型
Marc Gravell

@lupefiasco:OP的方便选择System.Timers.Timer;-p
Marc Gravell

嗯,以为您是在指概念而不是具体示例。Mea culpa。
肖恩·布莱特

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

2

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

MyClass myClassUT;

作为myClassUT主题ü的nDer 牛逼 EST。但是如果你想要编写单元测试与静态方法静态类?然后,您可以创建这样的别名:

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文件顶部使用别名并获得清晰的智能感知视图:

using SqlDataCon = System.Data.SqlClient.SqlConnection

现在来看我的智识观点。它是超透明和超干净的。

在此处输入图片说明


1

我知道的一个原因;当导入的名称空间发生名称冲突时,它可以使用较短的名称。例:

如果 在访问时在同一文件中声明了using System.Windows.Forms;using System.Windows.Input;ModifierKeys可能会发现该名称ModifierKeysSystem.Windows.Forms.ControlSystem.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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.