将C#知识转换为VB.NET任何潜在的问题?
我有一个团队,人们对C#非常熟悉,但我们要求在VB.net中编写一个项目。 在C#中思考并在飞行中转换为VB有多难? 那可行吗?
你能否列出我们可以遇到的问题?
我听说VB.net没有闭包。 对于.net 3.5来说,这仍然是真的吗?
如果您使用C#的思维方式接近VB.Net,最好在项目中设置以下选项
- 选项严格打开
- 选项明确的
- 选项推断
这基本上消除了VB.Net的后期绑定语义,并迫使它成为严格类型的语言。 这将使它更接近C#语义(无论如何仍然不准确)。
VB.Net从Visual Studio 2008 / .Net Framework 3.5版本开始支持Lambda Expression(以及Closure)。 不是表达而不是声明。 在VS2010 / .Net Framework 4.0之前不支持语句lambda。 虽然您可以使用4.0编译器来实现downtarget 2.0框架。
由于C#和VB.NET使用相同的框架并编译为非常相似的IL代码,因此您可以免费获得很多内容。 编写基本语法并不难。
C#语法更多的目的是显示正在发生的事情,而VB语法经常隐藏一些细节,因此C#程序员已经熟悉了一些对VB程序员来说根本不太明显的概念。 在某些方面,学习C#是学习VB工作方式比学习VB本身更好的方法…
我经常在不同的论坛上回答VB.NET问题,主要是基于我的C#知识,而且我自己还没有在VB.NET中编写简短的测试程序。
当然,在VB中需要注意一些怪癖。 就像/运算符一样,它总是将两个操作数都转换为double,或者使用VB特定比较代码的=操作数,而不是为.NET类中的相等运算符指定的比较。
VB.NET倾向于尝试掩盖的一个领域是处理事件; 其他人已经简要介绍了一些差异,但这里有一些更多:
VB.NET为引发事件的字段提供了WithEvents
关键字。 如果该字段声明为WithEvents
则可以将Handles field.Event
添加到其签名与事件兼容的方法的末尾; 该方法将自动成为事件的委托,而无需手动添加AddHandler
和RemoveHandler
( +=
和-=
)。
Private WithEvents SomeField Public Sub SomeField_SomeEvent(sender as Object, e as EventArgs) Handles SomeField.SomeEvent Console.Writeline("SomeEvent occured") End Sub
事件声明和引发事件有点简化。 在通知侦听器之前,VB.NET不要求您检查事件是否为null:
Public event SomeEvent as EventHandler(of SomeEventArg) Public Sub SomeMethod() RaiseEvent SomeEvent(Me, new EventArgs) End Sub
VB.NET中事件的一个“隐藏”特性是访问底层MulticastDelegate
,执行类似GetInvocationList()
注意:事件名为SomeEvent
,访问multicastdelegate的代码调用名为SomeEventEvent
的不可见字段:
Public event SomeEvent as EventHandler(of SomeEventArg) Public Sub SomeMethod() // Note that SomeEvent's MulticastDelegate is accessed by appending // another "Event" to the end, this sample is redundant but accurate. // If the event was named ListChanged then it would be ListChangedEvent dim invocationList = SomeEventEvent.GetInvocationList() End Sub
我发现的最大问题之一是VB的明显冗长。 它有所有这些大关键字,如MustInherit
, NotInheritable
, MustOverride
等,其中C#只有sealed
, abstract
和virtual
。 你必须有一个End
所有东西( End Sub
, End Function
, End While
, End Namespace
, End Class
等),你必须使用ReadOnly
关键字明确标记只读属性; 简单地省略setter就不会飞。 还要记住AndAlso
和OrElse
而不是更直观(但非短路) And
和Or
,以及Is Nothing
和IsNot Nothing
类的Is Nothing
,而不是== null
或!= null
。
这些都不一定是语言的问题 ,但是如果你已经习惯了C#的相对简单,那么VB代码对你来说可能看起来像是一大堆额外的东西。
2008年1月,Visual Studio杂志上有一些有用的文章。
- C#开发人员应该了解VB
- 为了完整起见 , VB开发人员应该了解C#
您可能也对“ 在C#中禁止VB中允许的内容(反之亦然) ”这一问题感兴趣
这里没有提到的一点是C#中的字段初始化程序在基本构造函数之前运行,而VB中的字段初始化程序在基本构造函数和派生类构造函数的第一个“真实”语句之间运行(在基本构造函数调用之后) ,如果有的话)。 这使得派生类中的字段初始值设定项可以使用基类成员(可能已使用传递给构造函数的参数进行初始化),但也意味着如果对象的基类构造函数在任何地方之前传递给它自己它返回,部分构造的对象可能在所有字段初始化程序运行之前使用。 在C#中,所有字段初始值设定项都将在基础构造函数开始执行之前运行,但是没有一个字段初始值设定项能够使用部分构造的对象。
PS – 如果C#背后的任何微软人员读到这一点,那么为字段声明添加一个上下文敏感的关键字是否有任何特别的困难,以指定它们是应该在基本构造函数之前还是之后处理,或者可能由某些人执行它们可以从构造函数调用的特殊方法,它可以包装在try-finally块中(这样可以清除所有分配的IDisposable)并且也可以使用传递给构造函数的参数?
我发现这是一篇突出差异的方便文章。 我是一名vb.net程序员,这有助于我找出c#代码,所以我相信它会以另一种方式工作!
http://www.codeproject.com/KB/dotnet/vbnet_c__difference.aspx
就像任何语言(人类或计算机)一样,你首先要学会“翻译”,然后你最终开始用另一种语言“思考”。
你的团队越快越好,越快越好。 所以,就像专家告诉你学习人类语言的方式一样:现实世界的例子和沉浸感。
在线提供了一些C#到VB.NET的转换实用程序,所以首先让团队用C#编写,转换为VB.NET,然后进行清理。 (转换实用程序的质量各不相同,但有一些限制,特别是对于较新的语言function。)
一旦他们掌握了基本的“语法”,就把它们放到VB.NET中100%。
我每天都使用它们,通常在不同的代码窗口中同时使用,并且没有问题上下文切换或在每个中做“正确的事情”。
除了Jared已经提到的,你应该没有问题。 唯一的另一个刺激源是奇怪的默认值。 EG您是否知道VB.NET项目默认隐藏解决方案资源管理器中的引用节点? (你必须选择ShowAllFiles才能看到它)。
我认为C#对VB.NET来说不会太痛苦,只是学习一种新语法的例子。 在当前版本中,两种语言的function相当紧密。
反之亦然(VB.NET到C#)可能会更难,因为人们可能会习惯使用’My’命名空间和其他东西来使VB6开发人员有宾至如归的感觉。
你需要注意一些微妙的差异。 例如,VB.Net没有短路if语句的概念(我已经纠正了,显然它确实如此)。 如果它只是一个短期项目,你可能不会有问题,但不同的语言确实有不同的方法来解决同样的问题。 这方面的一个例子是Python程序员谈论以“pythonic”方式做事。 他们在Dreaming in Code一书中讨论了这个概念,其中java程序员试图使用python语法编写java。 它导致了解决问题的漫长道路。 这会发生在C#和VB.Net上吗? 很难说,它们都使用底层框架工作,因此差异不会很大,但它仍然有助于尝试学习如何按照预期的方式使用VB.NET。
编辑:显然,它确实有短路的概念,但默认情况下它不会在C#中执行此操作。 这进一步certificate了学习语言function如何从长远来看是有益的。
我认为这不会太难。 VB.NET和C#是彼此接近的语言,只有语法真的不同。 当然,你的团队需要一些时间来适应新语言,但我认为你不会遇到大问题。
哦,VB.NET确实有闭包。 它缺少C#的其他一些function,如yield关键字,多语句lambdas和auto属性,但没有什么非常关键的。
如果您不想编写vb.net代码,可以选择在C#中编写项目,编译它,并使用Reflector查看vb.net等效内容。 无论如何,这一切都归结为MSIL!