【问题标题】: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 我没有暗示两者。我刚刚说明了为什么为类型设置自定义名称会很有用。

标签: c# namespaces


【解决方案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 中工作。

                【讨论】:

                  猜你喜欢
                  • 2012-12-27
                  • 2010-11-15
                  • 1970-01-01
                  • 2014-08-10
                  • 1970-01-01
                  • 2011-12-10
                  • 2010-12-02
                  相关资源
                  最近更新 更多