在Visual Basic中允许哪些在C#中被禁止(反之亦然)?

Ale*_*lex 14 c# vb.net

这与代码相关,就像编译器允许您使用一种语言一样,但不允许您使用其他语言(例如,在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)

  • +1这里是.NET CLR团队博客解释为什么异常过滤器有用的地方http://blogs.msdn.com/clrteam/archive/2009/02/05/catch-rethrow-and-filters-why-you-should- care.aspx (6认同)
  • 更新了.Net CLR博客帖子的链接[Catch,Rethrow和Filters - 你为什么要关心?](http://blogs.msdn.com/b/dotnet/archive/2009/02/05/catch-rethrow-and -filters - 为什么 - 你 - 应该-care.aspx).也感兴趣[异常过滤器的好坏](http://blogs.msdn.com/b/dotnet/archive/2009/08/25/the-good-and-the-bad-of-exception- filters.aspx) (2认同)

Tom*_*han 12

我很惊讶C#的不安全代码还没有被提及.这在VB.NET中是不允许的.


dss*_*539 11

VB 9.0编译器自动将文字XML转换为"功能构造"语法.C#编译器不支持这种不错的文字XML语法.

  • XML文字是VB的一个非常吸引人的方面! (2认同)

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直接执行此映射(这很好;实现方法不必共享名称).


Kon*_*lph 8

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).


Mar*_*rkJ 6

2008年1月,Visual Studio杂志上有一些有用的文章.


Tom*_*ter 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
Run Code Online (Sandbox Code Playgroud)

因为"Derived1"是一个基础,它可以访问"其他"的受保护成员,这也是一个基础.

C#采取了不同的观点.它不允许VB进行"侧向"访问.它表示可以通过"this"或与包含该方法的类相同类型的任何对象来访问受保护的成员.

因为这里的"Foo"是在"Derived1"中定义的,所以C#只允许"Foo"从"Derived1"实例访问"Base"成员."其他"可能不是"Derived1"(例如,它可能是"Derived2"),因此它不允许访问"m_x".


Mic*_*ows 5

脱离我的头顶(4.0之前):

C#中不支持VB语言"功能":

  • 可选参数
  • 后期绑定
  • 不区分大小写

我相信还有更多.如果您要求提供每种语言擅长的具体示例,您的问题可能会得到更好的答案.当与COM交互时,VB当前比C#更好.这是因为当可选参数可用时,以及在编译时不必绑定到(通常是未知类型)时,COM就不那么令人头疼了.

另一方面,C#在编写复杂逻辑时是优选的,因为它的类型安全性(因为你不能绕过静态类型)及其简洁性.

最后,语言大多是等同的,因为它们只在边缘上有所不同.在功能上,他们同样有能力.

编辑

需要明确的是,我不是暗示VB不允许静态类型......仅仅是C#不 [但] 允许你绕过静态类型.这使得C#成为某些类型架构的更具吸引力的候选者.在4.0 C#语言规范中,您可以绕过静态类型,但是您可以通过定义动态代码块来实现,而不是通过声明整个文件"不严格",这使得它更加有意识和有针对性.

  • VB.NET有Lambdas (2认同)
  • C#4.0具有可选参数.他们不想要他们,但没有他们让传统COM变得麻烦. (2认同)

Dil*_*e-O 5

我的最爱之一(和无赖)

在 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 对几乎任何东西执行“Select Case”的能力也很好 (3认同)

slo*_*ife 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
Run Code Online (Sandbox Code Playgroud)


rei*_*ein 5

VB 在函数上有可选参数。

C# 只会在 C# 4.0 中获得这些


Ric*_*son 5

在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使用.


Mar*_*rkJ 5

VB语言的一个被忽视或简单误解的特性是调用一个具有ByRef参数的函数.大多数语言仅支持通过引用传递参数的单一方法:即CLR直接支持的方案.

CLR对它支持的ByRef参数值的类型有很多限制,这些限制妨碍了VB成为灵活语言的目标.因此,编译器竭尽全力灵活并支持多种ByRef传递途径,远远超出了CLR原生允许的范围.

C#4 现在支持两种版本的引用传递.除了自1.0以后可用的ref修改器之外,在对COM对象进行互操作调用时,修改器现在是可选的.