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

时间:2009-06-08 19:14:27

标签: c# vb.net

这是与代码相关的,就像编译器允许您在一种语言中执行的操作一样,但不允许您使用其他语言(例如,在C#中不存在VB中的可选参数) )。

如果可能,请提供您的答案的代码示例。谢谢!

21 个答案:

答案 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)

用于自动连接EventHandlers的

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#对“受保护”的含义有不同的解释。

Here's an explanation复制如下:

  

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的唯一值)