我还没有看到有人对你在最后的明确第二个问题发表评论:“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#的实际代码示例:
while (txt.Length > x)
else if (allowLettersWithoutLimit && char.IsLetter(thisChar))
else if ((x2 = charsAllowedWithLimit.IndexOf(thisChar)) >= 0)
}
else
}
' 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.ToUpperInvariant
与
string 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#中),我甚至想不出在现实生活中它会有用处。因此,也许它根本不是一个缺陷。
祝编程愉快!