c# 获取命名空间下的所有类,

  c# 获取命名空间下的所有类,

  包与名称空间

  众所周知,可重用性是软件工程中一个非常重要的目标。复用,不仅意味着软件(代码、组件等。)自己写的可以重用;更广义地说,重用是指不同的人、不同的团队、不同的公司可以利用别人的成果。此外,大型软件往往由多个团队开发,这些团队可能分布在不同的城市、地区甚至国家。由于这些原因,名称管理成为一个非常重要的因素。

  由于C语言本身没有提供名称管理的机制(C语言的静态命名解决了可见性问题,这些名称不会导出到外部,但是我们要讨论的命名空间和这个问题并不完全一样),为了解决名称冲突的问题,人们一般选择前缀法;而前缀规则往往是:$ { projectname } _ $ { name }更安全的命名规则将前缀分为更多级别:$ { project name } _ $ { modulename } _ $ { name }。

  现实生活中类似这种方案的例子还有很多。比如中国很多城市都有滨河路。如果你交谈的所有人都知道你所指的城市,你只需要说滨江路,所有人都会明白你所指的城市。但如果不是这样,就需要加个前缀表示这是乐山的滨江路还是成都的滨江路。这一点在你邮寄信件的时候体现的最为直接。

  所以如果有全局管理的话,C语言的这个方案应该是很有效的。但它的缺点是可能会产生很长的名字,每次引用名字都要给出全名。

  这是一件很麻烦的事情。想象一下你每次说起“中国四川省乐山市滨河路”的时候会有多痛苦。

  为了解决这类问题,给出了有效的管理方案。后续的编程语言,无论是C、Java还是C#,都提供了自己的名字管理机制。这些方案在本质上都有自己统一的思路,但在操作模式上有所区别。

  在C语言之前的方案中,体现了分级管理。分级管理是一种非常自然有效的手段。比如互联网的域名。它通过分层命名保证了一个名字的全局唯一性,排列从小范围到大范围(这是因为西方的书写习惯和方便。其实从这一点可以发现,如果一个人的读前习惯是从左到右,从小到大的排列非常方便节省时间,比如“中国四川省乐山市滨河路”。当我们已经从左边的信息中知道我们的意思时,我们可以跳过或忽略下面的信息。而且由大到小的排列可以避免错误,因为我们先知道了限制条件,最后在读滨河路的时候就已经确定了自己的意思)。我们可以在前面加一个名字,指定一个更小的范围。例如,wsd.wmsg.sps.motorola.com解释说,这是摩托罗拉SPS部门wmsg部门的wsd小组。

  Java用这种方法命名Package,但是写法反过来。这种方法可以有效地保证命名的统一性。比如一个名为mlca的项目的mmi模块包可以命名为:com . Motorola . SPs . wmsg . wsd . mlca . MMI,而其引擎模块包可以命名为:com . Motorola . SPs . wmsg . wsd . mlca . engine。

  这样,当不同团队、不同公司的代码放在一起使用时,我们只需要简单地使用一个名字,不会发生冲突。当有冲突时,我们只需指定它的全名。例如,上面的两个包都有一个名为Message的类。如果我们另一个包中的一个类想要同时使用这两个包,那么在引用消息类时,我们需要指明它来自哪个包。如下所示:

  导入com . Motorola . SPs . wmsg . wsd . mlca . MMI;

  导入com . Motorola . SPs . wmsg . wsd . mlca . engine;

  //我们需要指明消息来自哪个包类。

  public class Foo extends com . Motorola . SPs . wmsg . mlca . mlca . MMI . message {

  .

  }

  C和C#提供了命名空间的概念来支持这种方法。可以在全局空间指定自己的命名空间,然后在某个命名空间做一个更小的命名空间。虽然C和C#本身并不推荐任何命名空间的命名方法(其实反域名的方法也是Java推荐的,并不强制),但是我们也可以使用上面的方法。例如,下面的C#代码:

  命名空间com . Motorola . SPs . wmsg . wsd . mlca . MMI

  {

  //MMI的东西

  .

  }

  命名空间com . Motorola . SPs . wmsg . wsd . mlca . engine

  {

  //引擎的东西

  .

  }

  当我们同时使用这两个模块时,如果存在名称冲突,可能会通过指定名称空间来指示。例如:

  class Foo:com . Motorola . SPs . wmsg . wsd . mlca . MMI . message

  {

  .

  }

  Java包本身没有子包的概念,所有包都是并行关系,不存在谁包含谁的问题。比如org.dominoo.action和org.dominoo.action.asl之间绝对没有包与子包的关系,它们是独立的包,每个包都有自己的类/接口集合。在org.dominoo.action.asl的java文件中,如果要引用org.dominoo.action中的类/接口,必须导入org.dominoo.action

  C /C#的命名空间方案是不同的。一个名称空间可以有自己的子名称空间。我们不妨称之为命名空间包,这样在C /C#中包与子包之间就可能有关系。例如:

  命名空间org.dominoo

  {

  命名空间操作

  {

  命名空间asl

  {

  .

  }

  }

  命名空间约束

  {

  名称空间ocl

  {

  .

  }

  }

  }

  在这个例子中,action和constraint都是org.dominoo的子包,它们有自己的子包asl和ocl。

  因此,对于一个全局命名空间,C语言不能直接分离命名空间,而Java可以从全局命名空间中分离出独立的命名空间,但C /C#可以进一步分离每个命名空间。如下图:

   -

  全局名称空间

   -

  c编程语言

   -

  全局名称空间

   - - -

   A B C

   - - -

   -

  java 3d

   -

  全局名称空间

   - -

   A B

   - - -

   C D E

   - - -

   - -

   -

  C /C#语言

  所以Java的包方案只划分一次全局命名空间。本质上,它只是为语言提供了一个命名前缀方案,只通过对命名前缀的分级管理来保证名称的唯一性。它唯一的功能是避免名称冲突。

  C /C#提供了细分任何空间的能力。在Java中,org.dominoo和org.dominoo.asl是完全没有关系的独立包,但在C /C#中,dominoo.asl显然是dominoo的一个子包。

  事实上,如果仅仅为了避免命名冲突而不需要C /C#这样的复杂方案,那么Java方案就足够了。但是C /C#方案可以带来其他便利:

  1.软件开发的本质是自顶向下的分解。每一层都有自己的定义,这个定义可以作为下一层所有子系统的公共服务。多级树形结构符合这个逻辑。C /C#方案以最自然的方式满足了这种划分关系。其实这个方案的思路和文档管理的思路是一样的。

  2.一旦一个程序使用了哪个名称空间,它就可以访问它的子包,而不用指出整个路径。比如上图,如果一个程序用命名空间A写,那么在访问C包中的类Foo时,只需要写C:Foo,而不用写完整路径:A:C:Foo。在Java中,由于A和C并置,为了访问C中的内容,必须明确指出导入C。然后,在访问Foo导致名称冲突的情况下,必须指出完整路径。

  3.当程序在一个包中时,它可以直接访问外部包中的定义,而不会发生名称冲突。因为Java包只有一个层次结构,所以Java只能直接访问全局命名空间中的定义,其他包中的任何定义都只能通过导入来访问。

  毫无疑问,C /C#的方案更强大、更灵活,但也更复杂。而复杂的东西往往会让用户更容易犯错。孰优孰劣,你可以自己判断。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

相关文章阅读

  • 设计一个简单的C#控制台应用程序,C#控制台程序,C# 创建控制台应用程序
  • 深入解析windows第8版,深入解析C#(第4版)
  • 数组代码,c# 数组操作,C# 数组实例介绍(图文)
  • 学会C#要多久,学会c#要多久,c#学习之30分钟学会XAML
  • 回溯法01背包问题c,回溯法求解01背包问题伪代码,C#使用回溯法解决背包问题实例分析
  • xml文件转义字符,xml转意字符,C# XML中的转义字符操作
  • winform 进度条控件,c# 进度条使用
  • winform 进度条控件,c# 进度条使用,C#使用winform实现进度条效果
  • winform backgroundworker,c# isbackground
  • winform backgroundworker,c# isbackground,C# BackgroundWorker用法详解
  • lua与c#交互,lua c#
  • lua与c#交互,lua c#,ToLua框架下C#与Lua代码的互调操作
  • linq c#,linq原理 c#
  • linq c#,linq原理 c#,c#中LINQ的基本用法实例
  • java decimal保留两位小数,sql中decimal函数保留2位小数,C#中decimal保留2位有效小数的实现方法
  • 留言与评论(共有 条评论)
       
    验证码: