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
这样的东西,并在声明文件以外的地方使用它。所以这个int
到Int32
的别名可能是通过其他方式实现的,或者是编译器/运行时的特殊事物。
@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.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)
【讨论】:
它可用于命名空间或类型名称的别名。 @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;
,您可能会发现名称ModifierKeys
在System.Windows.Forms.Control
和System.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# 命名空间别名 - 有啥意义?的主要内容,如果未能解决你的问题,请参考以下文章