VB是否真的不区分大小写?

128

我不是想发起争论,但通常说法是Visual Basic是大小写不敏感的,而C语言则不是(并且这似乎是一件好事)。

但是我的问题是:在Visual Basic中到底哪些部分是大小写不敏感的?当我输入...

Dim ss As String
Dim SS As String

在将代码插入到Visual Studio 2008Visual Studio 2010 IDE时,第二个IDE会出现警告“当前块中已经声明了局部变量SS”。在VBA VBE中,它不会立即发生错误,而是自动更正大小写。

我是否错过了什么,认为Visual Basic不区分大小写的论点?(如果您知道或愿意回答,为什么这样做是不好的?)

我为什么要提出这个问题?

多年来,我一直在使用Visual Basic的各种方言,有时作为业余爱好者,有时为小型企业相关程序在工作组中。在最近六个月中,我一直在开发一个大型项目,比我预期的要大得多。许多示例源代码都是用C#编写的。我没有任何迫切的愿望学习C#,但如果C#提供了Visual Basic没有的功能(相反,VB.NET提供了XML字面量),那么我想了解更多关于该功能的信息。因此,在这种情况下,经常有人争论C语言是区分大小写的,这很好,而Visual Basic不区分大小写,这很糟糕。我想知道...

  1. 既然编辑器中的每一个例子都变成了大小写敏感(也就是说它被自动更正),那么Visual Basic到底是如何不区分大小写的?
  2. 如果VB.NET的大小写方式在某种程度上限制了我的代码编写,那么这是否足以令我考虑转向C#?

5
我之前也曾对这件事感到好奇。 - NakedBrunch
10
不确定您是否理解"大小写不敏感"的含义。因为VB实际上是大小写不敏感的,所以SS和ss是相同的名称,而在C语言中它们则不同。 - Ed S.
1
宅男,我强烈建议将这个问题集中在VB不区分大小写的含义以及它是如何实现的上。关于语言是否应该不区分大小写的问题可能会引发争论。如果你真的很好奇,可以在另一个问题中提出。 (我建议你不要这样做,但如果你一定要这样做,那就打上主观标签并将其设为社区wiki) - MarkJ
19
你现在(或曾经)的想法是颠倒的。正是因为编译器不区分大小写,才会出现"变量SS已经声明"的错误提示。如果它是区分大小写的,你要么会得到一个"ss变量未使用"的提示,要么根本没有错误提示,但如果你交替使用大小写会出现bug。 - Adriano Varoli Piazza
1
我认为你没有意识到的是VB是“不区分大小写”的。这与许多其他流行语言(如C ++,C#,Java等)不同-因此对于编译器来说,ss与SS是相同的。 - Cam
显示剩余4条评论
13个回答

112
VBA和VB.NET的区别仅在于VB.NET在后台持续编译,当你编译VBA时会出现错误。
Jonathan所说的那样,在编程时,除了字符串比较、XML和其他一些情况外,你可以将VB.NET视为不区分大小写。
我想你对底层感兴趣。好吧,.NET Common Language Runtime是区分大小写的,而VB.NET代码依赖于运行时,因此在运行时必须区分大小写,例如在查找变量和方法时。
VB.NET编译器和编辑器让你忽略这个问题 - 因为它们会更正你的代码中的大小写。
如果你尝试使用动态特性或晚绑定(Option Strict Off),你可以证明底层运行时是区分大小写的。另一种看待这个问题的方式是,意识到像C#这样区分大小写的语言使用相同的运行时,因此运行时显然支持区分大小写。

编辑 如果你想把集成开发环境排除在外,你可以随时从命令行编译。在记事本中编辑你的代码,加上ssSS,然后看编译器会做什么。

编辑 引用Jeffrey Richter.NET Framework设计指南第45页的话。

需要明确的是,CLR实际上区分大小写。一些编程语言(如Visual Basic)是不区分大小写的。当Visual Basic编译器试图将方法调用解析为在C#这样的区分大小写语言中定义的类型时,编译器(而不是CLR)会找出方法名称的实际大小写并将其嵌入元数据中。CLR对此一无所知。现在,如果您正在使用反射来绑定到方法,则反射API提供执行不区分大小写查找的能力。这就是CLR提供不区分大小写的程度。


到目前为止,这是我听到的最好的答案。有没有什么方法可以证明这一点,即VB.Net编译器和编辑器让你忽略它?有没有办法关闭自动更正?或者有没有一种方法可以在MSBuild中编译一个不是在VS IDE中编写的sln,它使用ssSS,并且可以编译并按预期工作? - Todd Main
6
您可以通过一些小技巧来关闭自动校正。右键单击 VB 文件,选择“打开方式”,然后选择“XML(文本)编辑器”之类的选项。这样做会使您失去所有VB特定的功能,例如自动校正。 - Jonathan Allen
+1 很棒的回答,问题也很好,宅男(我想你已经知道了,但是想引出一个好的定义,对吧?) - Anonymous Type
VB.NET编译器/IDE并非完全不区分大小写。例如,Dim pdfWriter As PDFWriter是完全有效的。VB.NET允许您区分类名和变量名,这是一个很好的特点,因为在完全区分大小写的语言中这是常见做法。 - ingredient_15939
1
VB的方法对于互操作性是正确的。例如:使用C#创建一个DLL,其中包含电子邮件作为字符串和Email()作为属性,并在其中使用inotifypropertychanged事件。C#将编译成功并生成DLL。尝试在VB或任何类似语言中引用此DLL。它会说库中的变量电子邮件/Email存在冲突。代码分析工具指出这是C#编译器而不是VB编译器的问题。 - Venkat

23

这里的问题之一是需要将语言与IDE体验分开。

作为一种语言,VB.NET对标识符是忽略大小写的。调用DateTime.Parsedatetime.parse将绑定到完全相同的代码。与C#等语言不同的是,无法定义仅通过大小写区分的方法或类型。

作为一个IDE,当VB.NET按漂亮列表方式显示代码块时,它会尝试保留现有标识符的大小写。每当您移动到当前逻辑代码行以外时,都会发生漂亮的列表。在这种情况下,您移动到第二个SS声明之外,漂亮列表程序注意到存在具有该名称的现有标识符,并更正以匹配大小写。

然而,这种行为纯粹是作为用户附加值来完成的。它不是核心语言的一部分。


3
在我转换从 VBA/VB6/VB.NET 到 C# 之前,我也曾认为仅通过名称大小写差异来表示不同的事物似乎很危险。然而,在实践中,它被证明是相当有用的,而且令人惊讶的是,根本不容易出错。 - Mike Rosenblum
3
@Mike,我非常不同意这一点。我从未见过混合大小写的名称除了造成混乱之外还有其他作用。 - JaredPar
3
真的吗?我的意思是像 void SetColor(color Color) { this.color = color }; 这样的东西。我知道这看起来可能很危险,但它可以顺利地工作,编译器不会让你犯错,并且 IntelliSense 会在“color.”和“Color.”之后给出正确的成员。我在这里感到困扰的是,“this”的使用并不是必需的——它是由 FxCop 和/或 StyleCop 强制执行的,但我希望有一个设置,可以让 IDE 始终在访问类成员时强制执行这一点,而不是允许作用域被意外遮蔽。 - Mike Rosenblum
1
@Jared 噢,肯定,那将是一个疯狂的想法。完全贪婪。但总体而言,考虑到区分大小写语言允许的灵活性(包括您指出的一些非常糟糕的用法),我认为额外的灵活性是个小优点。另一方面,使用VB.NET时,我发现我必须在变量名前加上“the”或“my”来弥补这一点,这有点不幸。 - Mike Rosenblum
1
@MikeRosenblum 不是故意刁难(我也更喜欢C#),但在C#中,大小写真的很重要,所以函数参数应该是:SetColor(Color color){...}。 - Valentino Vranken
显示剩余6条评论

16

VB大多数情况下是不区分大小写的,但也有例外。例如,XML文本和推导式是区分大小写的。字符串比较通常是区分大小写的,不像T-SQL,但编译器有开关可以使字符串比较不区分大小写。当涉及到继承、COM和动态语言运行时等情况时,当然会有一些特殊情况。


3
关于 XML 文本和字符串比较等情况,大小写敏感确实很重要。但是当我们说某些情况下“大多数”情况下不区分大小写时,究竟是指什么呢?以 Outlook VBA 为例,如果我输入 Dim mi as mailitemsubject = mi.subject,对象名称会被自动更正为 MailItemmi.Subject。编译器会在意这一点吗(因为它总是自动更正这个)或者这只是为了好看呢? - Todd Main
2
编译器并不在意。你可以通过在记事本中编辑文件并使用命令行编译器来测试这一点。 - Jonathan Allen

9
是的,VB.NET编译器对标识符不区分大小写。这可能会在使用其他语言编写的程序集或使用COM组件时导致问题。前一种情况由公共语言规范覆盖。相关规则如下:

为了使两个标识符被视为不同,它们必须有更多不同之处,而不仅仅是它们的大小写。

COM的情况由类型库构建器粗略处理,它强制具有相同名称的标识符的大小写相同,即使这些标识符具有不同的角色。换句话说,具有名称“index”的方法参数将强制将方法名“Index”重新命名为“index”。这产生了相当多的困惑,正如您可以想象的那样 :)

8
VB是大小写保留的(在IDE中),但不区分大小写。这在某种程度上类似于Windows文件系统。Hello.txt和hello.txt被视为相同的文件名。
IDE假定变量声明是该变量的“正确”大小写,并调整每个匹配声明的变量实例。它这样做是为了美观和一致性,而不是为了功能。
我曾经看到过几个实例,在这些实例中,大小写没有自动更改以匹配声明,但语句仍然可以正常工作。您还可以使用任何文本编辑器编写代码,以不同的大小写进行编译。
附带说明: 大多数人以大小写不敏感的方式思考。当我们看到单词“dog”时,单词会在我们的头脑中转化为含义。单词的含义不基于大小写(即使拼写为“DOG”,“DoG”或“dOG”,狗仍然叫)。计算机将单词视为离散的位组。大写和小写是不同的位模式,因此是不同的。
由于大多数程序员都是人类,因此大小写不敏感似乎更适应人们的思维方式,而大小写敏感则更多是关于人类适应机器约束的方式。

5
除了程序员需要区分对象和类之外,他们通常使用大小写的变化来做到这一点(不是必需的,只是一个约定)。所以,如果你遵循这种编程惯例,object.method()Object.Method() 立即被认为是对象和类的引用和方法。英语中也是如此,你用大写字母区分专有名词和句子的开头。因此,在阅读或编程时,我不会忽略大小写,否则我可能会错过一些含义。 - Jason S
1
@Jason,这完全取决于你习惯什么。新的C编程学生一开始会对大小写敏感性提出无数抱怨,但是经过几门课程后就会习惯了。object.method()和Object.Method()只是一种约定,并且是大小写敏感性最强的例子。我曾经修改过别人写的一个程序,其中在同一作用域中有两个变量temp和Temp,我告诉你,很难区分它们。虽然我们可以通过大写字母来识别普通名词,但是“bob”和“Bob”在我们的大脑中意思相同。 - Andrew Neely
为什么IDE在这种情况下保留大小写?(抱歉)。我认为IDE保留大小写是因为微软的设计师认为大小写具有一定的语义,这在大脑中确实如此。但实际上,VB IDE认为formForm是相同的,这对我来说很困惑。在tempTemp的情况下,您可以轻松使用C#中的重构工具将Temp重命名为bobTemp或其他名称。然而,我正在维护一些VB代码,有人已经使用了Dim form As Form。现在当我重命名时,它会同时重命名类和对象引用。糟糕! - Jason S
@Jason,在VB中我总是说“Dim aform as Form”,但我离题了。VB支持大小写敏感的搜索。我会搜索“As Form”并将其替换为“somethingstupid”,然后将表单重命名为有意义的名称,最后将“somethingstupid”重新命名为“As Form”。实际上,我喜欢它改变大小写,因为它可以验证我没有打错变量名。 - Andrew Neely
是的,但这并不能替代重构工具,当名称相同时(或在VB中仅以大小写区分)它将区分类和实例引用。C#重构工具似乎能够做到这一点。我不会给类和实例取相同的名称。在C#中,我会使用大小写来区分,但在VB中我无法这样做,所以我会使用字母来添加前缀。显然,我的问题是我正在维护别人使用相同名称的代码。但是这个讨论已经太大了,所以我就在这里结束了。 - Jason S
+1 对于这个侧面的注释非常好!已经有足够大小写敏感的语言了! :) - Yarik

5

哦,那很有趣。有没有地方可以查找这些详细信息?我还没有测试过,但考虑到VBScript,你可能是对的。 - Todd Main
@Otaku:请再看一遍我的回答,我现在提供了链接。谢谢。 - Sarfraz
我非常熟悉VB,谢谢 :) 我不确定您想让我在那个页面上看什么。 - Todd Main

3

我不确定我是否理解你的意思?VB是大小写不敏感的,所以ss和SS是相同的变量,因此编译器正确地抱怨你重新声明了该变量。

我认为变量不区分大小写,但函数名是区分大小写的。


1
但是如果我使用 ss,然后稍后输入 SS,它会自动更正为 ss,这让我相信编译器确实关心大小写。 - Todd Main
6
这是IDE改变大小写,而不是编译器。 - John Saunders
2
VB 仍然不太关心大小写。IDE 正试图清理代码,使变量始终保持一致。 - guitarthrower

1

我还没有看到有人对你在最后的明确第二个问题发表评论:“2:如果VB.NET的情况在某种程度上限制了我的代码能力,那么这是否足够有吸引力让我考虑转向C#?”

我更喜欢C#提供的更多选择的方法,它让程序员可以选择,而不是限制程序员的选择。我非常喜欢C#,但仅仅因为它区分大小写,我不会觉得学习这门语言有多困难。所有的特性才是最重要的,当我比较C#和VB.NET的优势时,我非常偏爱C#。但我会给你一个真正公正的观点,尽管有偏见,因为我有自己的偏好,但我也会诚实地介绍C#的缺点。

首先,这两种语言都有各自的优点和缺点。一种语言中可以做到而另一种语言中不能做到的差异正在减少,幸运的是,微软正在改进这两种语言,并且它们似乎没有对任何一种语言显示不公平的偏爱。

当C#首次推出时,VB没有C#中可以放在方法之前的XML注释,而我却很喜欢。我讨厌VB.NET没有这个功能。但是多年来,我发现许多语言中没有的功能被添加到了另一种语言中。(微软开发人员团队同时开发C#和VB,所以这些功能变得相当相似是有意义的。)

但你问的是C#有什么VB没有的。以下是我能立即想到的一些:

1:C# 以许多方式更加简洁,输入的内容更少!我甚至看到了一些荒唐的言论声称,VB 能节省打字时间,但请听那些告诉你他们同时使用这两种语言的人的建议,他们很少使用任何一种语言。我在家里使用 C#,因为我喜欢它(而且当我在工作中使用 C# 时),我的最近一份工作要求我使用 VB 而不是 C#。所以我现在更经常地使用 VB(大约已经有10个月了),但根据我的亲身经历,我更喜欢 C#,而在实际输入方面,VB 需要更多的输入。我读到过一个人试图说 VB 更简洁的例子是给出一个带有长变量的 'with ...' 示例,所以在 VB 中,您可以只使用 '.属性'。这样声称 VB 需要更少输入是愚蠢的。有一些事情(不仅是这个例子)在 VB 上更短,但在实际应用中,C# 更加简洁。

但我认为C#更加简洁的最大原因是VB冗长的“IF/THEN”语句。在C#中,没有要输入的“then”单词! :) 此外,所有的“end…”语句都需要输入,在c#中通常只是一个闭合括号“}”。我读到有些人声称VB.NET中更多的冗长性是VB的优点,因为几个闭合块语句/符号可以嵌套并立即相邻结束,但我并不同意。一个人几乎总是能比另一个程序员更好地编写程序,因为下一次代码修订可以设计得更好。这也适用于“在C#中混淆了许多闭合括号”的情况,如果嵌套块全部是相同类型(例如几个嵌套IF),则VB遇到与C#相同的问题。这对VB来说不是优势。这正是为什么我喜欢在两种语言中注释我的闭合符号或闭合语句所在位置的原因。是的,这样做会更冗长,但在任何一种语言中,你都可以选择清晰明了,这在基于判断的特定情况下非常重要。我认为代码的清晰度非常重要。

2: VB 没有多行注释。当我使用 VB 时,我并不介意。然后我学了几种 C 风格的语言。现在我在工作中主要使用 VB.NET,我很想念它们。这只是你发现方便的东西,然后不得不失去它。:(

3: VB 的 'andalso' 和 'orelse' 在键入时相当烦人,而在 C# 中则简单得多,只需使用 '&&' 和 '||'。再次减少了键入量。这在我的 VB 和 C# 代码中都很常见。如果说功能上,“OR”和“OrElse”通常没有区别,除非“OrElse”对计算机来说更快,所以如果程序员只在 VB 中使用“Or”和“And”,那么它会产生不太优化的代码,对于喜欢清晰代码的人来说,“Or”比“OrElse”更容易阅读。

4:C#中代码放置更加灵活。当一行代码很长,你想将其换到下一行时,我讨厌VB.NET“控制”我的代码重新调整。C#会稍微调整一下,但我发现在C#中更有用,在VB中则更加控制。但这更多是VB.NET IDE与C# IDE的区别,而不是语言本身。但我不知道你是否想要两者都包括或仅包括语言特性而不涉及IDE差异。

5:我真正想念的一个功能是在C#中创建一个新的代码块,可能在一个方法中有很多事情发生,我想在一个非常小的代码块中声明一个变量,但不希望该变量在整个方法中声明。在C#中,我们可以使用“{”创建一个新的代码块,并以“}”结束。VB没有这样的功能,但最接近的匹配是无条件的“If True Then”和“End If”块。(注意2个字符的C#与18个字符的VB.NET等效项……在VB中需要更多的打字。)

6:自增和自减运算符:++和--,例如myVariable++++myVariable或相应的递减版本。这非常方便……有时候。以下是我非常想念C#的实际代码示例:

// C#:
while (txt.Length > x)
{
    thisChar = txt[x];
    if (charsAllowedWithoutLimit.Contains(thisChar)) { ++x; }
    else if (allowLettersWithoutLimit && char.IsLetter(thisChar)) { ++x; }
    else if ((x2 = charsAllowedWithLimit.IndexOf(thisChar)) >= 0)
    {
        ++x; if (++usedCountA[x2] > charAllowedLimit[x2]) { break; }
    }
    else { break; }
}

' VB.NET:
While (txt.Length > x)
    thisChar = txt(x)
    If (charsAllowedWithoutLimit.Contains(thisChar)) Then
        x += 1
    ElseIf (allowLettersWithoutLimit AndAlso Char.IsLetter(thisChar)) Then
        x += 1
    Else
        x2 = charsAllowedWithLimit.IndexOf(thisChar)
        If (x2 >= 0) Then
            x += 1
            usedCountA(x2) += 1S
            If usedCountA(x2) > charAllowedLimit(x2) Then Exit While
        Else
            Exit While
        End If
    End If
End While

只是为了举一个非常好的例子来证明C#的优势,以下是我最近亲自编写的更多代码:

// C#
public static bool IsNotWithin(this Byte   v, Byte   v1, Byte   v2) { return (v1 > v && v < v2) || (v2 < v && v > v1); }
public static bool IsNotWithin(this SByte  v, SByte  v1, SByte  v2) { return (v1 > v && v < v2) || (v2 < v && v > v1); }
public static bool IsNotWithin(this Int16  v, Int16  v1, Int16  v2) { return (v1 > v && v < v2) || (v2 < v && v > v1); }
public static bool IsNotWithin(this Int32  v, Int32  v1, Int32  v2) { return (v1 > v && v < v2) || (v2 < v && v > v1); }
public static bool IsNotWithin(this Int64  v, Int64  v1, Int64  v2) { return (v1 > v && v < v2) || (v2 < v && v > v1); }
public static bool IsNotWithin(this UInt16 v, UInt16 v1, UInt16 v2) { return (v1 > v && v < v2) || (v2 < v && v > v1); }
public static bool IsNotWithin(this UInt32 v, UInt32 v1, UInt32 v2) { return (v1 > v && v < v2) || (v2 < v && v > v1); }
public static bool IsNotWithin(this UInt64 v, UInt64 v1, UInt64 v2) { return (v1 > v && v < v2) || (v2 < v && v > v1); }
public static bool IsNotWithin(this Decimal v, Decimal v1, Decimal v2) { return (v1 > v && v < v2) || (v2 < v && v > v1); }

public static bool IsWithin(this Byte   v, Byte   v1, Byte   v2) { return (v1 <= v && v <= v2) || (v2 <= v && v <= v1); }
public static bool IsWithin(this SByte  v, SByte  v1, SByte  v2) { return (v1 <= v && v <= v2) || (v2 <= v && v <= v1); }
public static bool IsWithin(this Int16  v, Int16  v1, Int16  v2) { return (v1 <= v && v <= v2) || (v2 <= v && v <= v1); }
public static bool IsWithin(this Int32  v, Int32  v1, Int32  v2) { return (v1 <= v && v <= v2) || (v2 <= v && v <= v1); }
public static bool IsWithin(this Int64  v, Int64  v1, Int64  v2) { return (v1 <= v && v <= v2) || (v2 <= v && v <= v1); }
public static bool IsWithin(this UInt16 v, UInt16 v1, UInt16 v2) { return (v1 <= v && v <= v2) || (v2 <= v && v <= v1); }
public static bool IsWithin(this UInt32 v, UInt32 v1, UInt32 v2) { return (v1 <= v && v <= v2) || (v2 <= v && v <= v1); }
public static bool IsWithin(this UInt64 v, UInt64 v1, UInt64 v2) { return (v1 <= v && v <= v2) || (v2 <= v && v <= v1); }
public static bool IsWithin(this Decimal v, Decimal v1, Decimal v2) { return (v1 <= v && v <= v2) || (v2 <= v && v <= v1); }

' And the VB equivalent is a mess! Here goes:
<Extension()>
Public Function IsNotWithin(v As Byte, value1 As Byte, value2 As Byte) As Boolean
    Return (value1 > v AndAlso v < value2) OrElse (value2 < v AndAlso v > value1)
End Function

<Extension()>
Public Function IsNotWithin(v As SByte, value1 As SByte, value2 As SByte) As Boolean
    Return (value1 > v AndAlso v < value2) OrElse (value2 < v AndAlso v > value1)
End Function

<Extension()>
Public Function IsNotWithin(v As Int16, value1 As Int16, value2 As Int16) As Boolean
    Return (value1 > v AndAlso v < value2) OrElse (value2 < v AndAlso v > value1)
End Function

' the % suffix means 'As Integer' in VB.
<Extension()>
Public Function IsNotWithin(v%, value1%, value2%) As Boolean
    Return (value1 > v AndAlso v < value2) OrElse (value2 < v AndAlso v > value1)
End Function

' the & suffix means 'As Long' in VB.
<Extension()>
Public Function IsNotWithin(v&, value1&, value2&) As Boolean
    Return (value1 > v AndAlso v < value2) OrElse (value2 < v AndAlso v > value1)
End Function

<Extension()>
Public Function IsNotWithin(v As UInt16, value1 As UInt16, value2 As UInt16) As Boolean
    Return (value1 > v AndAlso v < value2) OrElse (value2 < v AndAlso v > value1)
End Function

<Extension()>
Public Function IsNotWithin(v As UInt32, value1 As UInt32, value2 As UInt32) As Boolean
    Return (value1 > v AndAlso v < value2) OrElse (value2 < v AndAlso v > value1)
End Function

<Extension()>
Public Function IsNotWithin(v As UInt64, value1 As UInt64, value2 As UInt64) As Boolean
    Return (value1 > v AndAlso v < value2) OrElse (value2 < v AndAlso v > value1)
End Function

' the @ suffix means 'As Decimal' in VB.
<Extension()>
Public Function IsNotWithin(v@, value1@, value2@) As Boolean
    Return (value1 > v AndAlso v < value2) OrElse (value2 < v AndAlso v > value1)
End Function

<Extension()>
Public Function IsWithin(v As Byte, value1 As Byte, value2 As Byte) As Boolean
    Return (value1 <= v AndAlso v <= value2) OrElse (value2 <= v AndAlso v <= value1)
End Function

<Extension()>
Public Function IsWithin(v As SByte, value1 As SByte, value2 As SByte) As Boolean
    Return (value1 <= v AndAlso v <= value2) OrElse (value2 <= v AndAlso v <= value1)
End Function

<Extension()>
Public Function IsWithin(v As Int16, value1 As Int16, value2 As Int16) As Boolean
    Return (value1 <= v AndAlso v <= value2) OrElse (value2 <= v AndAlso v <= value1)
End Function

' the % suffix means 'As Integer' in VB.
<Extension()>
Public Function IsWithin(v%, value1%, value2%) As Boolean
    Return (value1 <= v AndAlso v <= value2) OrElse (value2 <= v AndAlso v <= value1)
End Function

' the & suffix means 'As Long' in VB.
<Extension()>
Public Function IsWithin(v&, value1&, value2&) As Boolean
    Return (value1 <= v AndAlso v <= value2) OrElse (value2 <= v AndAlso v <= value1)
End Function

<Extension()>
Public Function IsWithin(v As UInt16, value1 As UInt16, value2 As UInt16) As Boolean
    Return (value1 <= v AndAlso v <= value2) OrElse (value2 <= v AndAlso v <= value1)
End Function

<Extension()>
Public Function IsWithin(v As UInt32, value1 As UInt32, value2 As UInt32) As Boolean
    Return (value1 <= v AndAlso v <= value2) OrElse (value2 <= v AndAlso v <= value1)
End Function

<Extension()>
Public Function IsWithin(v As UInt64, value1 As UInt64, value2 As UInt64) As Boolean
    Return (value1 <= v AndAlso v <= value2) OrElse (value2 <= v AndAlso v <= value1)
End Function

' the @ suffix means 'As Decimal' in VB.
<Extension()>
Public Function IsWithin(v@, value1@, value2@) As Boolean
    Return (value1 <= v AndAlso v <= value2) OrElse (value2 <= v AndAlso v <= value1)
End Function

也许这足以证明C#更加简洁。但并非所有程序员都喜欢简洁。有些人更喜欢读取“如果a < b,那么...”,因为它更符合他们的人类语言。这很好。偏好是可以接受的。对我来说,手动努力是我重视的因素,我认为任何人都可以习惯于使用他们喜欢的任何符号进行思考,“if”和“then”是字母表的符号,而C#的“if (condition) statement;”语法也是符号。其中一个只是比另一个更接近非程序员的语法。我更喜欢简洁的。

我还认为,在VB中需要在字符文字后面使用'c'使其成为字符文字而不是字符串很烦人。我更喜欢C#的简洁性。当方法需要一个字符文字时,你需要提供一个字符而不是长度为一个字符的字符串,所以有时你被迫在VB中使用":"c,而在C#中则是':'。我认为这是吹毛求疵。

公正地说,我要说我喜欢 VB 的优点,比如在方法调用之后不必放置空括号,例如: Dim nameUpper$ = name.ToUpperInvariant 而 C# 需要空括号: string nameUpper = name.ToUpperInvariant()。或者像这样将其裁剪两倍: Dim nameUpper$ = name.Trim.ToUpperInvariantstring nameUpper = name.Trim().ToUpperInvariant()。我喜欢 VB 简明的使用方式,就像我刚才使用 $ 在 '作为字符串' 中定义它一样,而 C# 没有这些捷径。VB 对于 String、Integer、Long、Decimal、Single 和 Double 类型都有这些捷径,但缺点是不够清晰,所以我谨慎使用。不过,无论如何,我更喜欢简洁的代码。
嗯,这只是一些经验丰富的程序员的想法,而当我考虑时,这就是我对 C# vs VB 的编程“证言”。 在我看来,两种语言都很好。但是,是的,我仍然更喜欢 C#。

顺便说一下,由于我计划终身从事编程,我甚至重新学习了使用最有效的键盘:Dvorak键盘,它在英语打字方面所需的努力只有Qwerty键盘的1/3。你可以查一下。也许你也想换一下。;) 它让我的打字变得轻松了67%! :) 我鼓励任何人思考超越常规,评估工作效率更高的方法。对我来说,Dvorak简化键盘布局和C#就是这样。

另外,我会将Dvorak和C#与公制相比较,而不是Qwerty键盘布局和VB与英制度量单位相比较。Dvorak、公制和C#都很“干净”。但VB并不差。但它确实需要向后兼容旧的VB6代码和预.NET代码,例如“Or”与“OrElse”以及“IIF()”。

我要提醒大家的是,请谨慎听取那些并不真正了解他们所说的话的人。对于VB和C#的所有缺点中,有一半已经不再是问题了,但仍有人在发帖子,却对语言中仍然存在的缺点一无所知。最好的例子就是使用三个撇号的VB或三个斜杠注释符的C#来为方法编写XML注释。但请自行判断一个人是出于无知还是经验而发表言论。个人证言意味着他们从自己的实际经验中获得了知识。当一个人拥有丰富的经验后,你就可以倾听他的建议。我在C#和VB方面拥有超过10年的经验,总结起来就是:两种语言都非常优秀。大多数差异,你可以在阅读代码的前5分钟内立即看到。但是,有些功能可能需要多年才能发现其缺陷。而我所知道的一个缺陷(在C#中),我甚至想不出在现实生活中它会有用处。因此,也许它根本不是一个缺陷。

祝编程愉快!


我很感激你提供的所有细节,但是就我所知,你的例子并没有使用大小写敏感性/不敏感性来展示为什么C#更好。 - Todd Main
我试图通过一个直接的例子来回答第二个问题。 - Venkat
@ToddMain,没错。我的例子没有使用大小写敏感性来展示为什么C#更好,因为问题并没有问为什么大小写敏感性使它更好。此外,我相信这个特性本身就说明了它的优点。而且我认为这个逻辑很基础,大多数人都可以自己推断出来。但如果有人问,我很乐意帮助他们理清逻辑。但是,我的朋友,我认为这是一个不同的问题。 ;) - Shawn Kovac
实际上,这是原帖中提出的两个问题之一。这并不是显而易见的,所以我才会问。但是不用担心没有回答问题。 - Todd Main
@ToddMain,我明白你的意思。确实是非常公正的观点。 :) 感谢你让我认识到这一点。 :) - Shawn Kovac

1

是的,VB不区分大小写。对于那些不习惯它的人来说,有时会让他们感到有点困惑。


1

我将尝试回答您的第二个问题。

"如果VB.NET限制了我的编程能力,那么这个理由足够让我考虑转向C#吗?"

使用C#创建WCF WebService。 创建一个DataContract(1个类)。 其中一个具有“string email”属性。 另一个具有“string Email”作为另一个属性。 你可以理解为个人电子邮件或办公室电子邮件。 或者它可以在两个不同的DataContract中。

对于C#来说,这很好。 Web服务已经成功创建。 C#程序可以轻松创建WSDL,一切正常。

现在尝试使用VB(任何版本)创建WSDL。 它会说“email”已经被声明,WSDL生成失败。

像所有人一样,我认为这是VB语言的缺点。 但是!!!

使用FxCOP分析原始的C#代码。 FxCOP说使用email/Email是一个问题。 建议使用支持大小写不敏感的不同名称。 还要注意,截至目前为止,.NET框架有106种编程语言,其中有许多语言开启了大小写敏感性。 我们都在向云端移动,并希望我们的服务可供所有编程平台/语言访问。

因此,在程序中选择大小写敏感是你的选择,如果你是C语言开发人员,你会喜欢它。如果该程序将被其他非C语言程序使用/访问,则需要支持大小写不敏感性,但语言由你决定。

http://en.wikipedia.org/wiki/Comparison_of_C_Sharp_and_Visual_Basic_.NET http://www.vbrad.com/article.aspx?id=65


云使用区分大小写的URI(这对代理和缓存服务器尤其重要)。 - binki

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