我没有看到任何人在最后对您明确的第二个问题发表评论:“2:如果 VB.NET 案例在某种程度上限制了我可以用代码做的事情,这是否足以让我考虑转向 C#?”
我更喜欢 C# 让程序员选择是否限制程序员的选项的更多选项方法。我非常喜欢 C#,但仅就区分大小写而言,我什至不认为它接近于学习一门语言,因为它区分大小写。所有的特性都很重要,当我看到 C# 和 VB.NET 两者的优点时,我非常喜欢 C#。但我会给你一个真正平衡的观点,有偏见,是的,因为我有一个偏好,但我也会诚实地说 C# 的缺点。
首先,两种语言都有优点和缺点。你可以用一种语言做而不能用另一种语言做的差异正在减少,幸运的是,微软正在改进这两种语言,而且他们似乎没有对这两种语言表现出不公平的偏袒。
当 C# 第一次出现时,VB 没有可以放在方法之前的 XML 注释,而我在 C# 中很喜欢这种注释。我讨厌在 VB.NET 中。但多年来我已经看到,许多不在一种语言中的功能被添加到另一种语言中。(同一个 MS 开发团队同时开发 C# 和 VB,因此功能应该变得非常相似是有道理的。)
但你问的是 C# 有什么 VB 没有。这里有一些我可以立即想到的:
1:C# 更简洁,输入更少……在很多方面!当提出相反的要求时,我什至看到过愚蠢的说法,即 VB 可以节省打字。但请听那些告诉你他们使用两种语言的人,而且他们很少使用任何一种语言。我同时使用 C#和VB,C# 在家,因为我喜欢它(当我在工作中使用 C# 时),我最近的工作要求我使用 VB 而不是 C#。所以我现在越来越频繁地使用 VB(大约 10 个月了),但在我个人的证词中,我更喜欢 C#,就实际打字而言,VB 的打字要多得多。我读过的一个例子是有人实际上试图说VB更简洁,给出了一个'with ...'示例,其中带有一个长变量,所以在VB中,你可以只使用'.property'。声称 VB 需要更少的输入是愚蠢的。在一些事情(不仅仅是这个例子)中,VB 更短,但在实际实践中,C# 更简洁的情况更多。
但我认为 C# 更简洁的最大原因是 VB 冗长的“IF/THEN”语句。if 语句很常见。在 C# 中没有“then”字可键入!:) 所有的 'end ...' 语句都需要输入,在 c# 中,通常只是一个右括号'}'。我读到有些人声称 VB.NET 中的这种更冗长是 VB 的一个优势,因为几个结束块语句/符号可以嵌套并立即彼此相邻结束,但我完全不同意。一个人几乎总是可以用 C# 或 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++
or++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# 更简洁的证据。但并不是所有的程序员都喜欢简洁。有些人更喜欢读“if a < b then ...”,因为这对他们的人类语言来说更自然。这很好。偏好很好。对我来说,手工是我看重的一个因素,我认为任何人都可以习惯于用他们喜欢的任何符号来思考,因为“if”和“then”是字母表的符号,而 C# 的“if(条件)语句”;语法也是符号。一个比另一个更接近非程序员的语法。我更喜欢简洁的。
我还认为需要在 VB 中的字符文字之后使用 'c' 使其成为字符文字而不是字符串很烦人。我更喜欢 C# 的简洁性。当一个方法需要一个字符文字时,你需要提供一个字符而不是一个字符长度的字符串,所以有时你被迫":"c
在 VB 中使用,而在 C# 中它是':'
. 我认为这是挑剔的。
公平地说,我会说我喜欢 VB 的一些优点,比如不必在方法调用后放置空括号,比如Dim nameUpper$ = name.ToUpperInvariant
C# 需要空括号:string nameUpper = name.ToUpperInvariant()
。或者像修剪它一样加倍:Dim nameUpper$ = name.Trim.ToUpperInvariant
vs string nameUpper = name.Trim().ToUpperInvariant()
. 我喜欢 VB 简洁地使用我刚刚在$
上面使用的方式将其调暗为“作为字符串”,而 C# 没有这些快捷方式。VB 有 String、Integer、Long、Decimal、Single 和 Double 类型的快捷键,但缺点是不太清楚,所以我谨慎使用。但是,我更喜欢简洁的代码。
好吧,这只是这位经验丰富的程序员的一些想法,而且我认为,这是我对 C# 与 VB 的编程“见证”。在我看来,两者都是不错的语言。但是,是的,我仍然更喜欢 C#。
ps 因为我打算在我的大部分时间里编程,所以我什至重新学会了使用最高效的键盘打字:Dvorak 键盘,与 Qwerty 键盘相比,打字所需的精力大约是 1/3。查一下。也许你也想切换。;) 它让我的打字轻松了 67%!:) 我鼓励任何人跳出框框思考并评估您工作中的更高效率。Dvorak Simplified Keyboard Layout 和 C# 为我完成了这项工作。:)
PSS 我会将 Dvorak 和 C# 与公制进行比较,而不是将 Qwerty 键盘布局和 VB 与 Empirial 测量进行比较。Dvorak、metric 和 C# 只是“干净”。但是 VB 并没有真正落后。但它确实需要向后兼容旧的 VB6 代码和 .NET 之前的代码,例如“Or”与“OrElse”和“IIF()”。
我谨慎地结束。请更加谨慎,不要听那些不知道他们在说什么的人。对 VB 和 C# 的所有缺点的一半不是不再有任何问题,人们仍然发帖说他们不知道该语言中仍然存在哪些缺点。我能想到的最好的例子是在 VB 中使用三撇号或在 C# 中使用三斜杠注释符号的方法的 XML 注释。但是请您自己辨别一个人是出于无知,还是出于经验。个人见证意味着他们从他们的真实经历中知道。在有人对此有很多经验之后,请竖起耳朵。我在 C# 和 VB 方面都有超过 10 年的经验。归结为:两者都是(非常)好的语言。而大部分差异,你可以在阅读代码的 5 分钟内立即看到。但是,是的,其他功能可能需要数年才能找到障碍。我知道的一个障碍(在 C# 中),我可以 甚至没有想到它会有用的现实生活情况。所以也许这毕竟不是一个障碍。
快乐编码!