这是与代码相关的,就像编译器允许您在一种语言中执行的操作一样,但不允许您使用其他语言(例如,在C#中不存在VB中的可选参数) )。
如果可能,请提供您的答案的代码示例。谢谢!
答案 0 :(得分:17)
VB.NET支持CIL异常过滤器,C#不支持:
Try
...
Catch ex As SomeException When ex.SomeProperty = 1
...
End Try
答案 1 :(得分:12)
我很惊讶C#的unsafe code还没有被提及。这在VB.NET中是不允许的。
答案 2 :(得分:11)
Handles和WithEvents关键字。
Private Sub btnOKClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnOK.Click
End Sub
答案 3 :(得分:11)
VB 9.0编译器自动将literal XML转换为“功能构造”语法。 C#编译器不支持这种不错的文字XML语法。
答案 4 :(得分:10)
在VB中,您可以使用任何名称的方法实现接口 - 即方法“Class.A”可以实现接口方法“Interface.B”。
在C#中,您必须引入额外级别的间接来实现此目的 - 调用“Class.A”的显式接口实现。
当您希望“Class.A”为protected
和/或virtual
(显式接口实现都不是)时,这一点非常明显;如果它只是“私有”你可能只是把它留作显式接口实现。
C#:
interface IFoo {
void B();
}
class Foo : IFoo {
void IFoo.B() {A();} // <==== extra method here
protected virtual void A() {}
}
VB:
Interface IFoo
Sub B()
End Interface
Class Foo
Implements IFoo
Protected Overridable Sub A() Implements IFoo.B
End Sub
End Class
在IL中,VB直接执行此映射(这很好;实现方法不必共享名称)。
答案 5 :(得分:8)
VB允许非虚拟调用虚拟实例方法(IL中为call
),而C#仅允许虚拟调用(IL中为callvirt
)。请考虑以下代码:
Class Base
Public Overridable Sub Foo()
Console.WriteLine("Base")
End Sub
Public Sub InvokeFoo()
Me.Foo()
MyClass.Foo()
End Sub
End Class
Class Derived : Inherits Base
Public Overrides Sub Foo()
Console.WriteLine("Derived")
End Sub
End Class
Dim d As Base = New Derived()
d.InvokeFoo()
输出结果为:
Derived
Base
这在C#中是不可能的(不使用Reflection.Emit
)。
答案 6 :(得分:6)
2008年1月,Visual Studio杂志上发表了一些有用的文章。
答案 7 :(得分:5)
VB和C#对“受保护”的含义有不同的解释。
WebControl的默认构造函数 受到保护。
VB和C#有所不同 对“受保护”的解释 装置
在VB中,您可以访问受保护的 来自任何方法的类的成员 任何派生自该类的类型。
也就是说,VB允许这个代码 编译:
class Base protected m_x as integer end class class Derived1 inherits Base public sub Foo(other as Base) other.m_x = 2 end sub end class class Derived2 inherits Base end class
因为“Derived1”是基础,所以它可以 访问“其他”的受保护成员, 这也是一个基地。
C#采取了不同的观点。它 不允许“侧身”访问 VB做的。它说访问 受保护的成员可以通过 “this”或任何相同类型的对象 作为包含方法的类。
因为这里定义了“Foo” “Derived1”,C#只允许“Foo” 从a访问“Base”成员 “Derived1”实例。它有可能 “其他”是不是的东西 “衍生1”(例如,它可能是 一个“Derived2”),所以它没有 允许访问“m_x”。
答案 8 :(得分:5)
One of the overlooked或者简单地误解了VB语言的功能是调用一个具有ByRef
参数的函数。大多数语言仅支持通过引用传递参数的单一方法:即CLR直接支持的方案。
CLR对ByRef
参数支持的值的类型有很多限制,这些限制妨碍了VB成为灵活语言的目标。因此,编译器竭尽全力灵活并支持ByRef
传递的多个途径,much beyond CLR原生允许的内容。
C#4 now supports两个版本的引用传递。除了从1.0开始的可用之外,ref
修饰符在对COM对象进行互操作时现在是可选的。
答案 9 :(得分:5)
在C#中,您可以将接口中的属性声明为具有“get”,然后在具有get和set的类中实现它。
public interface IFoo {
string Bar {get;}
}
public class Foo : IFoo {
public string Bar {get; set;}
}
在VB中,相当于用get来解析一个属性就是声明它是ReadOnly。然后,您无法使实现可写。
Public Interface IFoo
ReadOnly Property Bar() As String
End Interface
Public Class Foo
Implements IFoo
Public Property Bar() As String Implements IFoo.Bar 'Compile error here'
End Class
我发现这是VB的严重限制。我经常想要定义一个允许其他代码只能读取属性的接口,但我需要在实现的类中使用公共setter,供persistor使用。
答案 10 :(得分:5)
VB.NET中允许使用索引属性,但C#
中不允许 Private m_MyItems As New Collection(Of String)
Public Property MyItems(ByVal index As Integer) As String
Get
Return m_MyItems.Item(index)
End Get
Set(ByVal value As String)
m_MyItems.Item(index) = value
End Set
End Property
答案 11 :(得分:5)
脱离我的头顶(4.0之前):
C#中不支持VB语言“功能”:
我相信还有更多。如果您要求提供每种语言擅长的具体示例,您的问题可能会得到更好的答案。当与COM交互时,VB当前比C#更好。这是因为当可选参数可用时,以及在编译时不必绑定到(通常是未知类型)时,COM就不那么令人头疼了。
另一方面,C#由于其类型安全性(因为你无法绕过静态类型)及其简洁性而在编写复杂逻辑时更受欢迎。最后,语言大多是等同的,因为它们只在边缘上有所不同。在功能上,他们同样有能力。
修改强>
要说清楚,我并不是说VB不允许静态输入......只是 C#不 [还] 允许你绕过静态输入。这使得C#成为某些类型架构的更具吸引力的候选者。在4.0 C#语言规范中,您可以绕过静态类型,但是您可以通过定义动态代码块来实现,而不是通过声明整个文件“不严格”,这使得它更加有意识和有针对性。
答案 12 :(得分:4)
我的最爱之一(和无赖)
在VB.Net中,你可以这样构造一个switch / case语句:
Select Case True
Case User.Name = "Joe" And User.Role = "BigWig" And SecretTime = "HackerTime"
GrantCredentials()
End Select
允许您通过开关而不是各种if / else块来评估一些复杂的评估。你不能在C#中做到这一点。
答案 13 :(得分:4)
volatile关键字仅在C#http://www.devcity.net/Articles/160/5/article.aspx
中可用答案 14 :(得分:4)
VB在函数上有可选参数。
C#只能用C#4.0获取这些
答案 15 :(得分:3)
在VB中禁止以C#结尾的每一行的分号,当我尝试回到VB.Net时,这总是让我微笑......
答案 16 :(得分:3)
尚未为VB.NET完成C#中的新autoproperties。
答案 17 :(得分:2)
在C#中,您必须先分配变量才能使用它。我想你可以关闭它,但这是默认行为。
这样的事情:
int something;
if (something == 10)
{ ... }
是不允许的,但VB的等价物是。
答案 18 :(得分:2)
正如Chris Dunaway所提到的,VB.NET具有允许您定义函数和数据的模块。
VB.NET具有用于链接到DLL中的方法的VB6语法。例如:
Declare SetSuspendState Lib "powrprof" As Function (byval hibernate as Int32, byval forceCritical as Int32, byval disableWakeEvent) as Int32
(虽然实际的声明可能必须是Marshalled)
答案 19 :(得分:1)
c#i中不存在全局变量
答案 20 :(得分:0)
当转换为整数时VB.Net中的True将转换为-1,而在C#中它将转换为1.
此外,VB.Net中的NOT关键字确实是一个按位NOT(如在C#'〜'中),而不是逻辑NOT(C#'!')。
对于AND和OR运算符,VB.Net已经有逻辑运算符AndAlso And OrElse,它们是真正的逻辑运算符和短路,仍然没有逻辑运算符。
这在处理Win32 API时尤其重要,其中假设如果结果为True,则NOT会否定它,这是错误的,因为在C = = 1,因此按位不是1也是一个真值(这实际上可能是VB中为true == -1的原因,因为这是按位NOT将导致0的唯一值)