我应该使用与.NET BCL名称冲突的类名吗(否则最优)?

10

可能有些情况对你们中的一些人来说并不罕见:你有一些功能要放在一个类中,但这个类的完美名称(*)已经被System命名空间或其他不属于你的命名空间/类中的一个类占用了,但你正在使用该类。

(*)我所说的完美是指名称小、简洁和清晰。

例如,我有一个Utils类,其中有一个Diagnostics(主要是调试工具)类和一个Drawing类。 我可以:

  1. 有一个DrawingUtils类和一个DiagnosticsUtils类,但那只是不好的结构。
  2. 选择一本词典就结束了,但这样会得到更糟、更长或者让人感觉奇怪的名字,而且通常仍然没有被占用。
  3. 将类名用我的母语写出来,而不是英语。
  4. 向StackOverflow上的聪明人请教。

我认为选项1-3并不可取 :(

编辑:

由于我选择的答案没有明确解决问题,我建议面对相同情况的人们问自己:您是否经常使用冲突的BCL类/命名空间? 如果没有,那么就让你的名称冲突(就像我对诊断所做的那样)。如果是,请添加一个限制您的类/命名空间可能性的单词。

实际上,这意味着:
"Drawing": 画图的东西。
"MyCustomControlDrawing": MyCustomControl中绘制的东西。例如:"WidgetDrawing"

编辑2:

下次可以看看另外一个解决方案:扩展方法(感谢Lawnmower提供)。


“L'art pour l'art” - 为艺术而艺术。那就是我对你的问题的看法。第一个解决方案是很好的,为什么不采用呢?我认为我们每天工作中还有更重要的问题。 :P - Łukasz W.
@Łukas:如果我在生命中成功解决了一个小问题,下一次遇到同样的问题时,我会更快地找到解决方案。 - Camilo Martin
1
我不这么认为。有一天,我也曾经认为某些问题有完美的解决方案,如果我发现了它,那么以后我就知道如何解决这些问题了...但事实并非如此。不同的项目,不同的人在工作,所有的规则都会完全不同于这里;)我不反对这样的问题;)这是一个好问题...只是要意识到这些答案并不是终极的;) - Łukasz W.
7个回答

8

我认为保留 DrawingDiagnostics 等名称是没有问题的。这也是命名空间的一个目的,用于解决命名冲突。


这就是我对“诊断”所想的,但我会广泛地使用两个不同的“绘图”类,并且它们彼此非常接近。 - Camilo Martin

6
命名空间的美妙之处在于它允许您创建具有相同名称的类。当您使用 using 语句将其导入到文件中时,可以给命名空间分配一个别名。
using MyAlias = My.Custom.Namespace;

这样可以将你的类与微软的类分开。
然后,您可以引用您的类作为:
MyAlias.Diagnostics

或者你可以给Microsoft的命名空间分配一个别名,但我不建议这样做,因为它会让其他开发人员感到困惑。


1
这正是我使用微软试图独占的类名的方法。 - Joseph Yaduvanshi
2
实际中这很烦人。我总是忘记添加这一行。VS不会自动使用正常的快捷方式添加所有其他using行。如果阅读使用别名的代码,很容易感到困惑。如果您需要来自两个命名空间的两个类,那么您的代码将被Mycompany.myproject.mysubproject.mymodule.MyClass淹没。不用了,我宁愿有一个不太完美的名称。 - Stefan
我曾经在一个使用WPF Toolkit datagrid和内置datagrid控件的WPF应用程序中遇到了这个问题。我不得不给Microsoft.Windows.Controls起别名,因为它有许多与System.Windows.Controls相同的名称。我同意这有点烦人,但是对于每个类名附加“Utils”也是同样的情况。 - Scott M.

5
对我来说,特意编写冲突的类名并不值得麻烦。你会让其他不熟悉你的代码库的开发人员感到困惑,因为他们期望使用BCL类,但最终却使用了你的类(反之亦然)。这样,当他们不得不编写特定的using别名时,你只是浪费了他们的时间。
老实说,想出有意义的标识符名称是一项有用的技能,但这并不值得拖延你的开发。如果你不能很快想出好的名称,就安心地选一个平庸的名称并继续前进。在名称上花费太多时间是没有多少价值的。我敢说你可以做更有成效的事情。
编辑:我也不认为“小”是“完美”标识符的组成部分。简洁明了,当然没问题,但如果需要更长的名称来传达特定构造的目的,那就这样吧。毕竟我们有智能感知。

特别是考虑到现代开发环境中重命名事物的简易性。有时候,对于某些东西来说,完美的名称直到你使用它一段时间后才会想到。 - Matt Greer
不知道为什么会被踩,但对我来说小是简洁的一个组成部分。我讨厌短小的名称,但是过长的代码行对于可读性来说几乎和短小的名称一样糟糕。 - Camilo Martin
小和简洁是不同的术语。简洁准确描述了一种传达大量信息并保持简短的术语,而我会警告不要仅为了拥有一个小名称而使用“小”术语。在可读性方面肯定需要取得平衡。 - JoshJordan
我说过要小而简洁而清晰,除了简短等于小之外。当然,如果需要的话,它也应该很长。 - Camilo Martin
不完全是这样。你说“小”是“简洁”的一个组成部分。这是正确的,并且也是澄清的原因。这种区别很重要。简洁是可取的,但为了简洁而简洁并不可取。 - JoshJordan

4

使用命名空间可以将您的类与其他命名空间中的类区分开来。要么使用完全限定的名称,要么使用一个using语句告诉编译器你需要什么:

using Type = MyReallyCoolCustomReflector.Type;

现在,如果您仍想使用System命名空间中的Type类:
System.Type sysType = anObject.GetType();

通常情况下,我会尽量避免名称重复,但这并不总是能够实现。我也喜欢简单、易读和易于维护的代码。因此,这往往是一个权衡决策。


选择这个答案是因为你表达得非常清楚:“这是一个权衡”。 - Camilo Martin

1

如果你想避免命名空间冲突,有几件事情可以做:


  • 不要冲突,相反选择一个独特的名称。

例子:

如果你正在创建一个数学类,你可以将其命名为CamiloMartin.MathHelper


  • 使用长命名空间来区分冲突。

示例:

public class MyClass
{
    public int SomeCalculation(int a, int b)
    {
        return MyNamespace.Math.SomeFunc(a, b);
    }
}

使用别名进行区分。 示例:
using System.Math;
using SuperMath = MyNamespace.Math;

namespace MyNamespace
{
    public class MyClass
    {
        public int SomeCalc(int a, int b)
        {
             int result = Math.abs(a);
             result = SuperMath::SomeFunc(a, b);

             return result;
        }
    }
}

1

仅供记录:.NET Framework 没有 UtilsDiagnostics 类。但是有 System.Diagnostics 命名空间。

个人而言,我不喜欢像 Utils 这样的通用类,因为它们的方法不太容易发现(通常要么太通用,要么太具体),因此我只会将它们用作内部类。

至于其余方面--我同意其他人的观点,命名空间很方便。(尽管如果 System 中已经有一个同名的类,我会再三考虑命名该类的原因,这并不是因为名称冲突,而是因为我不能使用“原始”类的原因可能意味着我即将创建的类在语义上是不同的。)


我从不使用来自不同程序集的“Utils”之类的东西,那是内部的东西。 - Camilo Martin
PS:我有没有说过Diagnosticsnamespace - Camilo Martin
@Camilo Martin,你没有。我只是下意识地回想起为什么一个类不应该被命名为其命名空间(http://blogs.msdn.com/b/ericlippert/archive/2010/03/09/do-not-name-a-class-the-same-as-its-namespace-part-one.aspx)...但这对你的情况无关紧要。 - Regent

1
通常可以选择更具体的名称。例如,考虑 Utils。绝对可以将任何东西称为实用程序。对于您代码的读者来说,这个类名毫无价值。
通常,实用程序类是一组没有真正适合其他地方的方法。尝试将它们放在它们所属的位置,或按某些标准对它们进行分组,然后使用该组作为类名。根据我的经验,这种分组总是可能的。
总的来说:
  1. 这就是我们正在做的事情(嘿,我们以后可以重构它)

  2. 仅在重要的类上使用了一两次。特别有用,如果您还不知道“完美”的名称。

  3. 甚至不要考虑这个...

使用命名空间别名并不好玩。因此,如果可以的话,我会避免使用它。

我的“Utils.Drawing”中有一个方便的lockbits包装器,用于快速setPixel()。另一个是RGB<>HSL实用程序。我认为这些应该在System.Drawing命名空间中。 - Camilo Martin
1
根据它们处理的数据类型,您可能需要考虑使用扩展方法。然后类名就不再影响了。我会将RGB<>HSL放入单独的ColorSpaceConverter类中。早晚您都需要更多的颜色空间 :) - Stefan
嗯,谢谢你的推荐。我会看一下扩展方法的! :) - Camilo Martin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接