C#名称空间别名-what';重点是什么?
在何处或何时使用名称空间别名C#名称空间别名-what';重点是什么?,c#,namespaces,C#,Namespaces,在何处或何时使用名称空间别名 using someOtherName = System.Timers.Timer; 在我看来,这只会增加对语言理解的混乱。这是一个类型别名,而不是名称空间别名;消除歧义很有用,例如,针对: using WinformTimer = System.Windows.Forms.Timer; using ThreadingTimer = System.Threading.Timer; (ps:感谢您选择计时器;-p) 否则,如果在同一个文件中同时使用System
using someOtherName = System.Timers.Timer;
在我看来,这只会增加对语言理解的混乱。这是一个类型别名,而不是名称空间别名;消除歧义很有用,例如,针对:
using WinformTimer = System.Windows.Forms.Timer;
using ThreadingTimer = System.Threading.Timer;
(ps:感谢您选择计时器
;-p)
否则,如果在同一个文件中同时使用System.Windows.Forms.Timer
和System.Timers.Timer
,则必须不断给出全名(因为Timer
可能会让人困惑)
它还具有extern
别名,用于使用来自不同程序集的具有相同完全限定类型名的类型-非常罕见,但需要支持
实际上,我可以看到另一种用法:当你想快速访问一个类型,但不想使用常规的
使用,因为你不能导入一些冲突的扩展方法。。。有点复杂,但是。。。这里有一个例子
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) { }
}
}
namespace Something.From.SomeCompanyA {
public class Foo {
/* ... */
}
}
namespace CompanyB.Makes.ThisOne {
public class Foo {
/* ... */
}
}
当您在多个包含的名称空间中有多个同名的类时,它非常有用。例如
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) { }
}
}
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 Utility = MyBaseNamespace.MySubNamsepace.Utility;
其中,Utility
将具有不同的上下文(如MyBaseNamespace.MySubNamespace.MySubNamespace.Utility
),但我希望/更希望Utility
始终指向该特定类。简洁
在共享类型名称的名称空间之间提供清晰性有一些附带的好处,但本质上它只是一种糖。当我有多个子名称空间和/或对象名称冲突的名称空间时,我会使用它,您可以这样做[作为示例]:
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();
它节省了大量的键入工作,并且可以使代码更易于阅读。我们已经为所有名称空间定义了名称空间别名。这使得查看类的来源变得非常容易,例如:
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.
及
我们已经定义了一些关于别名命名和每个人都在使用别名的指导原则。除了上面提到的示例之外,当重复引用泛型类型时,类型别名(而不是名称空间别名)非常方便:
Dictionary<string, SomeClassWithALongName> foo = new Dictionary<string, SomeClassWithALongName>();
private void DoStuff(Dictionary<string, SomeClassWithALongName> dict) {}
Dictionary foo=newdictionary();
私有无效文件(字典dict dict){}
与:
using FooDict = Dictionary<string, SomeClassWithALongName>;
FooDict foo = new FooDict();
private void DoStuff(FooDict dict) {}
使用FooDict=字典;
FooDict foo=新的FooDict();
私有无效文件(FooDict dict){}
我发现别名在单元测试中非常有用。在编写单元测试时,通常将要测试的主题声明为
MyClass myClassUT;
作为myClassUT
受试者UndTest。但是如果您想用静态方法为静态类编写单元测试呢?然后,您可以创建如下别名:
using MyStaticClassUT = Namespace.MyStaticClass;
public void Test()
{
var actual = MyStaticClassUT.Method();
var expected = ...
}
然后您可以这样编写单元测试:
using MyStaticClassUT = Namespace.MyStaticClass;
public void Test()
{
var actual = MyStaticClassUT.Method();
var expected = ...
}
而且你永远不会忘记测试的对象是什么。在某种程度上,在Visual Studio中编写代码非常方便
用例:假设我只使用了几个类,例如命名空间系统.Data
中的SqlConnection
。正常情况下,我将导入*.cs文件顶部的System.Data.SqlClient
命名空间,如下所示:
using System.Data;
现在看看我的智能感知。在代码编辑器中输入时,它大量增加了大量的类供选择。我根本不打算使用所有的类:
因此,我宁愿在*.cs文件顶部使用别名,以获得清晰的intellisense视图:
using SqlDataCon = System.Data.SqlClient.SqlConnection
现在看看我的智能感知观点。它是超清晰和超清洁的
我知道一个原因;它允许您在导入的名称空间发生名称冲突时使用较短的名称。
例如:
如果您使用System.Windows.Forms声明使用System.Windows.Input进行编码>和<编码>在同一文件中,当您访问ModifierKeys
时,您可能会发现名称ModifierKeys
同时位于System.Windows.Forms.Control
和System.Windows.Input
名称空间中。
因此,通过使用Input=System.Windows.Input声明
然后可以通过Input.ModifierKeys
获取System.Windows.Input.ModifierKeys
我不是一个C#buff,但别名名称空间对我来说似乎是“最佳实践”。这样,您就可以知道您得到了什么,并且仍然不必键入太多内容。您可以使用它们非常轻松地修改代码
例如:
#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
中工作,它可以用于别名名称空间或类型名称。@Sean:是的,但给出的示例是type@lupefiasco:操作方便,可选择系统.定时器.定时器
-帕,我以为你指的是这个概念,而不是具体的例子。这是罪魁祸首。你不觉得别名通常与其说与对象的物理位置有关,不如说与使用它的上下文有关吗?在C#中使用int=system.Int32作为系统范围的?很有用,不是吗?这与其他地方可以利用的用途相同。@nawfal我认为类型别名是不可导出的。这意味着您不能使用int=System.Int32定义类似于的内容,并在声明文件之外的其他位置使用它。所以这个int
到Int32
的别名可以通过其他方式实现,或者是编译器/运行时中的特殊功能。@KFL这是真的,但是两者所带来的好处是相同的。@nawfal你关于使用int=System.Int32
的论点既错误又有误导性——这是错误的,因为int
别名没有按照你描述的方式实现。这是误导性的,因为您暗示类型别名可以全局使用,就像int
如何在Int32
上使用一样