Преобразование знаний C# в VB.NET есть потенциальные проблемы?
У меня есть команда с людьми, которые чувствуют себя достаточно комфортно в C#, но у нас есть требование написать проект на VB.net. Насколько сложно было бы думать на C# и на лету конвертировать в VB? Это выполнимо?
Не могли бы вы перечислить проблемы, с которыми мы можем столкнуться?
Я слышал, что у VB.net нет закрытий. Это все еще верно для.net 3.5?
13 ответов
Если вы приближаетесь к VB.Net с мышлением C#, лучше всего установить следующие параметры в проекте
- Вариант Строгое Вкл
- Опция Явный Вкл
- Опция Infer On
Это по существу удаляет семантику позднего связывания VB.Net и заставляет его быть строго типизированным языком. Это приблизит его к семантическому смыслу C# (но все же не совсем точно).
VB.Net имеет поддержку лямбда-выражений (и, следовательно, Closure), начиная с выпуска Visual Studio 2008 / .Net Framework 3.5. Не выражение и не утверждение. Лямбды операторов не поддерживаются до VS2010 / .Net Framework 4.0. Хотя вы можете использовать 4.0 компилятор, чтобы снизить 2.0 фреймворки.
Поскольку C# и VB.NET используют одну и ту же инфраструктуру и компилируют очень похожий IL-код, у вас есть много бесплатного. Написание базового синтаксиса не так сложно.
Синтаксис C# больше нацелен на то, чтобы показать, что происходит, в то время как синтаксис VB часто скрывает некоторые детали, поэтому программист C# уже знаком с некоторыми понятиями, которые могут вообще не быть очевидными для программиста VB. В некотором смысле изучение C# - лучший способ узнать, как работает VB, чем изучение самого VB...
Я часто отвечаю на вопросы VB.NET на разных форумах, в основном основываясь на моих знаниях C#, и я до сих пор не написал ничего, кроме коротких тестовых программ на VB.NET.
Есть, конечно, некоторые причуды, на которые нужно обратить внимание в VB. Как, например, оператор /, который всегда преобразует оба операнда в двойной, или операнд =, который использует специальный код сравнения 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 не требует, чтобы вы проверяли, является ли событие нулевым, до уведомления слушателей:
Public event SomeEvent as EventHandler(of SomeEventArg)
Public Sub SomeMethod()
RaiseEvent SomeEvent(Me, new EventArgs)
End Sub
Одна "скрытая" особенность событий в VB.NET - доступ к базовым MulticastDelegate
, чтобы сделать что-то вроде GetInvocationList()
Примечание: событие называется SomeEvent
и код для доступа к многоадресной передаче вызывает невидимое поле с именем 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
В январе 2008 года в журнале Visual Studio было несколько полезных статей.
Вас также может заинтересовать вопрос " что разрешено в VB, что запрещено в C# (или наоборот)"
Точка, которая здесь не упоминалась, состоит в том, что инициализаторы полей в C# выполняются перед базовым конструктором, тогда как инициализаторы в VB выполняются между базовым конструктором и первым "реальным" оператором конструктора производного класса (после вызова базового конструктора)., если таковые имеются). Это позволяет инициализаторам поля в производном классе использовать членов базового класса (которые могли быть инициализированы с использованием параметров, переданных в конструктор), но также означает, что если конструктор базового класса объекта проходит сам где-то раньше возвращается, частично созданный объект может быть использован до того, как все инициализаторы поля запустятся. В C# все инициализаторы полей будут выполняться до того, как базовый конструктор начнет выполнение, но ни один из инициализаторов полей не сможет использовать частично созданный объект.
PS - если кто-нибудь из Microsoft, стоящий за C#, прочтет это, возникнет ли какая-то особая трудность при добавлении контекстно-зависимого ключевого слова для объявлений полей, чтобы указать, должны ли они обрабатываться до или после базового конструктора, или, возможно, их выполнит какой-то специальный метод, который может быть вызван из конструктора, который может быть обернут в блок try-finally (чтобы любые выделенные таким образом IDisposables могли быть очищены) и мог бы также использовать параметры, передаваемые конструктору?
Одна из самых больших проблем, которые я обнаружил, - очевидное многословие VB. У него есть все эти большие ключевые слова, такие как MustInherit
, NotInheritable
, MustOverride
и т. д., где C# просто имеет такие вещи, как sealed
, abstract
а также virtual
, Вы должны иметь End
ко всему (End Sub
, End Function
, End While
, End Namespace
, End Class
и т. д.) И вы должны явно пометить свойства только для чтения с помощью ReadOnly
ключевое слово; простое опускание сеттера не сработает. Также помня AndAlso
а также OrElse
вместо более интуитивного (но не короткого замыкания) And
а также Or
и тому подобное Is Nothing
а также IsNot Nothing
вместо == null
или же != null
,
Ни одна из этих проблем не обязательно является проблемой с языком, но если вы привыкли к относительной простоте C#, код VB может показаться вам лишним.
Как и любой язык (человеческий или компьютерный), вы сначала учитесь "переводить в своей голове", а затем начинаете "думать" на другом языке.
Чем быстрее ваша команда сможет совершить этот прыжок, тем лучше. Итак, сделайте это так же, как эксперты говорят вам, чтобы выучить человеческий язык: реальные примеры и погружение.
В Интернете есть несколько утилит для преобразования C# в VB.NET, поэтому начните с того, что команда напишет на C#, преобразует в VB.NET и очистит его. (Утилиты преобразования различаются по качеству и имеют некоторые ограничения, особенно с использованием новых языковых функций.)
Как только они освоят базовую "грамматику", поместите их на VB.NET на 100%.
Я использую их каждый день, часто в разных окнах кода одновременно, и у меня нет проблем с переключением контекста или выполнением "правильных действий" в каждом из них.
Я считаю, что это удобная статья, освещающая различия. Я программист на vb.net, и это помогает мне понять код на C#, так что я уверен, что он будет работать по-другому!
http://www.codeproject.com/KB/dotnet/vbnet_c__difference.aspx
Принимая во внимание возраст этого вопроса, этот вопрос, вероятно, сейчас довольно хорошо известен, но я добавлю одну большую ошибку, которую я видел с точки зрения написания VB.NET, как пользователь C#:
Nothing
не означает null
, это означает default(T)
Это значит, что...
Dim a As Integer = Nothing
Dim b As Integer? = Nothing
... полностью действителен и фактически означает...
int a = default(int); // 0
int? b = default(int?); // null
Ответ Джона М. Ганта касается того факта, что есть специальные ключевые слова для сравнения сNothing
-смысл-null
- Is Nothing
а также IsNot Nothing
но, если вы забудете и воспользуетесь =
, вы можете получить неожиданный результат, который трудно отследить:
Dim a As Integer? = Nothing
If a = Nothing Then Console.WriteLine("a = Nothing")
If a <> Nothing Then Console.WriteLine("a <> Nothing")
If a Is Nothing Then Console.WriteLine("a Is Nothing")
If a IsNot Nothing Then Console.WriteLine("a IsNot Nothing")
'Output:
'a Is Nothing
Это, по крайней мере, улавливается предупреждениями компилятора (BC42037 и BC42038), поэтому вы можете заставить эти предупреждения быть ошибками в вашем файле VBPROJ.
Помимо того, что Джаред уже упоминал, у вас не должно быть проблем с этим. Единственный источник раздражения - странные настройки по умолчанию. EG Знаете ли вы, что проекты VB.NET по умолчанию скрывают узел ссылок в обозревателе решений? (Вы должны выбрать ShowAllFiles, чтобы увидеть его).
Я не думаю, что это будет слишком сложно. VB.NET и C# являются языками, которые близки друг к другу, только синтаксис действительно отличается. Конечно, вашей команде понадобится некоторое время, чтобы привыкнуть к новому языку, но я не думаю, что вы столкнетесь с большими проблемами.
Да, и у VB.NET есть замыкания. В C# отсутствуют некоторые другие функции, такие как ключевое слово yield, лямбда-выражения нескольких операторов и автоматические свойства, но ничего особо важного.
Один из вариантов, если вам не хочется писать код vb.net, - это написать свой проект на C#, скомпилировать его и использовать Reflector, чтобы увидеть, как выглядит эквивалент vb.net. В любом случае все сводится к MSIL!
Есть некоторые тонкие различия, на которые вам следует обратить внимание. Например, VB.Net не имеет понятия короткого замыкания в операторе if (я был исправлен, по-видимому, так и есть). Если это всего лишь краткосрочный проект, у вас, вероятно, не будет проблем, но разные языки имеют разные подходы к решению одной и той же проблемы. Примером этого являются программисты на Python, говорящие о том, чтобы делать что-то "питоническим" образом. Об этой концепции они рассказывают в книге "Мечты в коде", где программисты Java пытались программировать Java с использованием синтаксиса Python. Это приводит к долгому пути к решению проблемы. Произойдет ли это с C# и VB.Net? Трудно сказать, они оба используют базовую структуру фрейма, поэтому различия не будут огромными, но это все равно поможет попытаться узнать, как использовать VB.NET так, как это было задумано.
Редактировать: так, очевидно, у него есть концепция короткого замыкания, но он не делает это по умолчанию, где C# делает. Это еще раз доказывает, что изучение языка может быть полезным в долгосрочной перспективе.
Я думаю, что C# для VB.NET не будет слишком болезненным, это всего лишь случай изучения нового синтаксиса. В текущих версиях возможности обоих языков довольно тесно связаны.
Обратный путь (от VB.NET к C#) может быть сложнее, потому что люди могут привыкнуть использовать пространство имен "Мой" и другие вещи, добавленные туда, чтобы разработчики VB6 чувствовали себя как дома.