这与代码相关,就像编译器允许您使用一种语言一样,但不允许您使用其他语言(例如,在C#中不存在VB中的可选参数).
如果可能,请提供您的答案的代码示例.谢谢!
bzl*_*zlm 17
VB.NET支持CIL异常过滤器,C#不支持:
Try
...
Catch ex As SomeException When ex.SomeProperty = 1
...
End Try
Run Code Online (Sandbox Code Playgroud)
Lur*_*eed 11
Handles和WithEvents关键字,用于EventHandler的自动连接.
Private Sub btnOKClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnOK.Click
End Sub
Run Code Online (Sandbox Code Playgroud)
Mar*_*ell 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() {}
}
Run Code Online (Sandbox Code Playgroud)
VB:
Interface IFoo
Sub B()
End Interface
Class Foo
Implements IFoo
Protected Overridable Sub A() Implements IFoo.B
End Sub
End Class
Run Code Online (Sandbox Code Playgroud)
在IL中,VB直接执行此映射(这很好;实现方法不必共享名称).
VB允许非虚拟调用虚拟实例方法(call在IL中),而C#只允许虚拟调用(callvirt在IL中).请考虑以下代码:
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()
Run Code Online (Sandbox Code Playgroud)
输出是:
Derived
Base
Run Code Online (Sandbox Code Playgroud)
这在C#中是不可能的(不诉诸Reflection.Emit).
VB和C#对"受保护"的含义有不同的解释.
WebControl的默认构造函数受到保护.
VB和C#对"受保护"的含义有不同的解释.
在VB中,您可以从派生自该类的任何类型的任何方法访问类的受保护成员.
也就是说,VB允许这段代码编译:
Run Code Online (Sandbox Code Playgroud)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"从"Derived1"实例访问"Base"成员."其他"可能不是"Derived1"(例如,它可能是"Derived2"),因此它不允许访问"m_x".
脱离我的头顶(4.0之前):
C#中不支持VB语言"功能":
我相信还有更多.如果您要求提供每种语言擅长的具体示例,您的问题可能会得到更好的答案.当与COM交互时,VB当前比C#更好.这是因为当可选参数可用时,以及在编译时不必绑定到(通常是未知类型)时,COM就不那么令人头疼了.
另一方面,C#在编写复杂逻辑时是优选的,因为它的类型安全性(因为你不能绕过静态类型)及其简洁性.
最后,语言大多是等同的,因为它们只在边缘上有所不同.在功能上,他们同样有能力.
编辑
需要明确的是,我不是暗示VB不允许静态类型......仅仅是C#不 [但] 允许你绕过静态类型.这使得C#成为某些类型架构的更具吸引力的候选者.在4.0 C#语言规范中,您可以绕过静态类型,但是您可以通过定义动态代码块来实现,而不是通过声明整个文件"不严格",这使得它更加有意识和有针对性.
我的最爱之一(和无赖)
在 VB.Net 中,您可以这样构造 switch/case 语句:
Select Case True
Case User.Name = "Joe" And User.Role = "BigWig" And SecretTime = "HackerTime"
GrantCredentials()
End Select
Run Code Online (Sandbox Code Playgroud)
它允许您通过 switch 而不是各种 if/else 块来评估一些复杂的评估。您不能在 C# 中执行此操作。
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
Run Code Online (Sandbox Code Playgroud)
在C#中,您可以将接口中的属性声明为具有"get",然后在具有get和set的类中实现它.
public interface IFoo {
string Bar {get;}
}
public class Foo : IFoo {
public string Bar {get; set;}
}
Run Code Online (Sandbox Code Playgroud)
在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
Run Code Online (Sandbox Code Playgroud)
我发现这是VB的严重限制.我经常想要定义一个允许其他代码只能读取属性的接口,但我需要在实现的类中使用公共setter,供persistor使用.